package com.shop2cn.iapi.sqoptrade.testcase;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import com.shop2cn.iapi.activitymgt.parameter.response.ActivityCatalogVo;
import com.shop2cn.iapi.sqoptrade.parameter.vo.*;
import com.shop2cn.iapi.sqoptrade.verify.DGSQPlaceOrderVerifyService;
import com.ymttest.business.service.shenqi.*;
import com.ymttest.business.service.shenqi.bean.SqStockService;
import org.apache.commons.collections.CollectionUtils;
import org.joda.time.DateTime;
import org.junit.*;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.google.common.collect.Lists;
import com.shop2cn.iapi.cdfgeteway.resp.PointsVo;
import com.shop2cn.iapi.points.resp.CalcOrderCreditResp;
import com.shop2cn.iapi.shenqisettlement.parameter.bean.AgentProductBean;
import com.shop2cn.iapi.sqoptrade.parameter.enums.CouponTypeEnum;
import com.shop2cn.iapi.sqoptrade.parameter.enums.PromotionTypeEnum;
import com.shop2cn.iapi.sqoptrade.parameter.enums.RiskControlStatusEnum;
import com.shop2cn.iapi.sqoptrade.parameter.model.placeorder.MainOrder;
import com.shop2cn.iapi.sqoptrade.parameter.model.placeorder.Order;
import com.shop2cn.iapi.sqoptrade.parameter.model.placeorder.OrderGroup;
import com.shop2cn.iapi.sqoptrade.parameter.model.placeorder.OrderItem;
import com.shop2cn.iapi.sqoptrade.parameter.req.CdfDeductCouponBeforePlaceReq;
import com.shop2cn.iapi.sqoptrade.parameter.req.PlaceOrderReq;
import com.shop2cn.iapi.sqoptrade.parameter.utill.Utils;
import com.shop2cn.iapi.sqoptrade.resp.CdfDeductCouponBeforePlaceResp;
import com.shop2cn.iapi.sqoptrade.resp.PlaceOrderResp;
import com.shop2cn.iapi.sqoptrade.resp.TradingServiceResp;
import com.shop2cn.iapi.sqoptrade.resp.vo.CouponAmountVo;
import com.shop2cn.iapi.sqoptrade.service.PlaceOrderCall;
import com.ymatou.common.lang.CipherUtil;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.SQPayGateWayCallService;
import com.ymttest.business.service.shenqi.bean.PackageInfoByCatalogIdListResponse;
import com.ymttest.business.service.shenqi.bean.ShenqiUserSet;
import com.ymttest.business.service.shenqi.bean.SubCatalog;
import com.ymttest.database.model.DGUserInfo;
import com.ymttest.database.sharding.db.ext.model.OrderDetailExtPo;
import com.ymttest.database.sharding.db.ext.model.OrderExtPo;
import com.ymttest.database.sharding.db.sharding.model.OrderBizPo;
import com.ymttest.database.sharding.db.sharding.model.OrderCouponDetailPo;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailPo;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailPromotionPo;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailSubPo;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.ShenqiProxyChainPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.database.sharding.db.sqlwapper.OrderWapper;
import com.ymttest.database.sqlwapper.DGUserWapper;
import com.ymttest.database.sqlwapper.shenqi.SqliveOrderDetailWrapper;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.TestDataManager;
import com.ymttest.utils.YMTDateUtil;
import com.ymttest.utils.constant.ECode;

public class Ts_SqPlaceBookingOrder {

	private PlaceOrderReq placeOrderReq;
	private static PlaceOrderCall placeorderCall;

	DGSQPlaceOrderVerifyService verifyService = new DGSQPlaceOrderVerifyService(placeOrderReq, placeorderCall);
	
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();
	
	private static OrderWapper orderWapper = new OrderWapper();
	private static SqliveOrderDetailWrapper sqliveOrderDetailWrapper = new SqliveOrderDetailWrapper();
	
	private static long multiCDFCodeGoodsOwnerId = ShenqiUserSet.multiCDFCodeGoodsOwnerId;
	private static long cdfMembergoodsOwnerId = ShenqiUserSet.cdfMembergoodsOwnerId;
	private static long autotest_goodsOwnerId = ShenqiUserSet.autotest_goodsOwnerId;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("创建订单(新)接口");
		String accountid1;
		try {
			accountid1 = AccountCallServiceV2.getAccountId(20238699);
			AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
					9000000), new BigDecimal(0));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Before
	public void caseUp() {
		placeOrderReq = new PlaceOrderReq();
		placeorderCall = new PlaceOrderCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(placeorderCall.getOpurl());
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	@After
	public void caseDown() {
		Logger.end();
	}
	
	private MainOrder buildOrder(List<PlaceOrderReq> bookingPlaceOrderReqList) throws Exception {

		MainOrder mainOrder = new MainOrder();

		mainOrder.setPlaceOrderReq(placeOrderReq);
		
		// 各订单分摊折扣的权重
		List<BigDecimal> orderWeightsDiscount = new ArrayList<BigDecimal>();
		
		// 各订单分摊积分抵扣金额的权重
		List<BigDecimal> orderWeightsIntegralDeduction = new ArrayList<BigDecimal>();

		// 所有订单
		List<Order> allOrders = new ArrayList<Order>();
		
		String currency = Utils.nullIsCNY(placeOrderReq.getCurrency());
		
		// 整个支付单的店主总毛利润
		BigDecimal totalProxyProfit = BigDecimal.ZERO;

		for (OrderGroupVo groupVo : placeOrderReq.getOrderGroups()) {

			OrderGroup group = new OrderGroup();

			group.setOrderGroupVo(groupVo);
			mainOrder.getOrderGroups().add(group);

			BigDecimal totalProductPriceInSellerCoupon = BigDecimal.ZERO;
			
			int orderCount = 0;

			BigDecimal serviceRate = group.getOrderGroupVo().getServiceRate();
			
			Boolean isCDFCoupon = false;
			
			List<CouponVo> sellerCoupons = new ArrayList<>();
			
			CouponVo sellerCoupon = groupVo.getSellerCoupon();
			
			// 中免不使用优惠券叠加
			if (null != sellerCoupon) {

				isCDFCoupon = SqTradingCallService.isCDFCoupon(Utils
						.zeroIfNull(sellerCoupon.getCouponSource()));

				sellerCoupons.add(sellerCoupon);
			}

			if (null != groupVo.getSellerCoupons()) {

				for (CouponVo c : groupVo.getSellerCoupons()) {

					isCDFCoupon = SqTradingCallService.isCDFCoupon(Utils
							.zeroIfNull(c.getCouponSource()));
					sellerCoupons.add(c);
				}
			}

			if (!DataUtil.isNullOrEmpty(bookingPlaceOrderReqList)) {

				List<OrderVo> bookingOrderList = groupVo.getOrders().stream()
						.filter(OrderVo -> Utils.falseIfNull(OrderVo.getBookingConfirmOrder()))
						.collect(Collectors.toList());
				
				for (int i = 0; i < bookingPlaceOrderReqList.size(); i++) {

					OrderVo orderVo = bookingOrderList.get(i);

					orderVo.setEquipmentId(bookingPlaceOrderReqList.get(i)
							.getEquipmentId());
					orderVo.setDeviceId(bookingPlaceOrderReqList.get(i)
							.getDeviceId());
					orderVo.setSourceIp(bookingPlaceOrderReqList.get(i)
							.getSourceIp());
					orderVo.setAutoCancelOrderHours(bookingPlaceOrderReqList
							.get(i).getOrderGroups().get(0).getOrders().get(0)
							.getAutoCancelOrderHours());
					orderVo.setSalesman(bookingPlaceOrderReqList.get(i)
							.getSalesman());
					orderVo.setPaymentStartTime(bookingPlaceOrderReqList.get(i)
							.getOrderGroups().get(0).getOrders().get(0)
							.getPaymentStartTime());
					orderVo.setPaymentEndTime(bookingPlaceOrderReqList.get(i)
							.getOrderGroups().get(0).getOrders().get(0)
							.getPaymentEndTime());
					orderVo.setLeaveWord(bookingPlaceOrderReqList.get(i)
							.getOrderGroups().get(0).getOrders().get(0).getLeaveWord());
					orderVo.setLogisticsType(bookingPlaceOrderReqList.get(i)
							.getOrderGroups().get(0).getOrders().get(0).getLogisticsType());
				}
			}

			for (OrderVo orderVo : groupVo.getOrders()) {

				Order order = new Order();

				if (Utils.falseIfNull(orderVo.getBookingConfirmOrder())) {

					order.setEquipmentId(orderVo.getEquipmentId());
					order.setDeviceId(orderVo.getDeviceId());
					order.setSourceIp(orderVo.getSourceIp());
					order.setSalesman(orderVo.getSalesman());
				} else {
					
					order.setEquipmentId(placeOrderReq.getEquipmentId());
					order.setDeviceId(placeOrderReq.getDeviceId());
					order.setSourceIp(placeOrderReq.getSourceIp());
					order.setSalesman(placeOrderReq.getSalesman());
				}

				order.setOrderVo(orderVo);
				order.setSellerId(groupVo.getSellerId());

				allOrders.add(order);
				
				order.setCurrency(currency);
				order.setCurrencySymbol(placeOrderReq.getCurrencySymbol());

				BigDecimal orderFreight = BigDecimal.ZERO;
				BigDecimal orderGrossProfit = BigDecimal.ZERO;

				orderCount = orderCount + 1;
				int orderItemCount = 0;
				Boolean afterAcctivityFinishAccept = null;
				BigDecimal totalProductPrice = BigDecimal.ZERO;

				// 是否为分销订单
				boolean isInheritedOrder = false;

				// 是否为直销订单
				boolean isDirectSellOrder = order.getSellerId() == orderVo
						.getGoodsOwnerId();

				if (!isDirectSellOrder) {

					isInheritedOrder = GodmchManageCallService
							.isInheritedAgent(order.getSellerId());

					order.setIsProxy(true);
					order.setIsInherited(isInheritedOrder);
				}

				for (OrderItemVo orderItemVo : orderVo.getOrderItems()) {

					BigDecimal productPriceInSellerCoupon = BigDecimal.ZERO;
					
					OrderItem orderItem = new OrderItem();

					orderItem.setItemVo(orderItemVo);

					order.getOrderItems().add(orderItem);

					if (Utils.falseIfNull(orderItemVo
							.getFullReductionFreeFreight()))
						orderFreight = orderFreight.add(BigDecimal.ZERO);
					else
						orderFreight = orderFreight.add(Utils
								.zeroIfNull(orderItemVo.getFreight()));

					// 累计订单的总成交价
					BigDecimal productPrice = orderItemVo
							.getProductPrice()
							.multiply(
									new BigDecimal(orderItemVo.getProductNum()));
					BigDecimal proxyPrice = null;
					
					totalProductPrice = totalProductPrice.add(productPrice);

					// 如果是直销商
					if (isDirectSellOrder) {

						proxyPrice = BigDecimal.ZERO;
						orderItem.setServiceRate(serviceRate);
					} else {

						List<ShenqiProxyChainPo> shenqiProxyChain = new ArrayList<>();
						boolean isPlatformSupplierOrder = false;

						if (isInheritedOrder) {

							shenqiProxyChain = SqTradingProductService
									.getInheritedProxyChainInfo(
											orderItemVo.getCatalogId(),
											order.getSellerId());

							proxyPrice = shenqiProxyChain.get(
									shenqiProxyChain.size() - 1)
									.getFromParentPrice();
						} else {

							shenqiProxyChain = SqTradingProductService
									.getProxyChainInfoList(orderItemVo
											.getCatalogId(), order.getSellerId());

							proxyPrice = shenqiProxyChain.get(
									shenqiProxyChain.size() - 1)
									.getFromParentPrice();

							isPlatformSupplierOrder = GodmchManageCallService
									.queryPlatformBindRelation(orderVo
													.getGoodsOwnerId(),
											shenqiProxyChain.get(1)
													.getSellerId());
						}

						orderItem.setShenqiProxyChain(shenqiProxyChain);
						order.setIsPlatformSupplierOrder(isPlatformSupplierOrder);
					}

					// 获得该商品的毛利润
					BigDecimal productProxyProfit = orderItemVo
							.getProductPrice()
							.subtract(proxyPrice)
							.multiply(
									new BigDecimal(orderItemVo.getProductNum()));
						
					orderItem.setOrderItemGrossProfit(productProxyProfit);

					order.getOrderItemWeightsOnFreight().add(totalProductPrice);

					order.setTotalProductPrice(totalProductPrice);

					int couponCount = 0;

					if (sellerCoupons.size() == 0) {

						order.getOrderItemWeightsOnSellerCoupon().add(
								BigDecimal.ZERO);
						productPriceInSellerCoupon = BigDecimal.ZERO;
					} else {

						Boolean addTotalProductPriceInSellerCoupon = false;

						for (CouponVo c : sellerCoupons) {
							if (c != null
									&& DGSQPlaceOrderVerifyService.couponApplicable(orderItemVo, c)
									&& !Utils.falseIfNull(orderItemVo
											.getExchangeBuy())) {

								couponCount = couponCount + 1;

								if (isCDFCoupon) {

									order.setSellerCouponCode(c.getCouponCode());
									order.setSellerCouponSource(c
											.getCouponSource());
									order.setSellerCouponType(c.getCouponType());
								} else {

									// 如果是多个优惠券，则订单上只保留第一张券的信息
									order.setSellerCouponCode(sellerCoupons
											.get(0).getCouponCode());
									order.setSellerCouponSource(sellerCoupons
											.get(0).getCouponSource());
									order.setSellerCouponType(couponCount > 1 ? -1
											: sellerCoupon.getCouponType());

									productPriceInSellerCoupon = productPrice;

									if (!addTotalProductPriceInSellerCoupon) {

										// 订单中适用商家优惠券的成交价总额
										order.setTotalProductPriceInSellerCoupon(order
												.getTotalProductPriceInSellerCoupon()
												.add(productPriceInSellerCoupon));

										totalProductPriceInSellerCoupon = totalProductPriceInSellerCoupon
												.add(productPriceInSellerCoupon);
										order.getOrderItemWeightsOnSellerCoupon()
												.add(productPrice);
									}

									addTotalProductPriceInSellerCoupon = true;
								}
							}
						}
					}

					totalProxyProfit = totalProxyProfit.add(productProxyProfit);
					orderGrossProfit = orderGrossProfit.add(productProxyProfit);

					orderItemCount = orderItemCount + 1;

					if (placeOrderReq.getDiscount() != null) {

						// 商品分摊折扣的权重按照商品价格
						order.getOrderItemWeightsOnDiscount().add(productPrice);
					}

					if (null != orderItemVo.getActivity()) {

						if (Utils.falseIfNull(orderItemVo.getActivity()
								.getAfterActivityFinishAccept())
								|| Utils.falseIfNull(afterAcctivityFinishAccept)) {
							afterAcctivityFinishAccept = true;
						} else {
							afterAcctivityFinishAccept = false;
						}
					} else
						afterAcctivityFinishAccept = Utils
								.falseIfNull(afterAcctivityFinishAccept);
				} // end orderItems

				order.setFreight(orderFreight);
				order.setGoodsOwnerId(orderVo.getGoodsOwnerId());
				order.setShenqiLogisticsType(orderVo.getShenqiLogisticsType());
				order.setShenqiIdCardRequirement(orderVo
						.getShenqiIdCardRequirement());
				order.setAfterAcctivityFinishAccept(afterAcctivityFinishAccept);
				order.setOrderGrossProfit(orderGrossProfit);
				
				group.getOrderWeightsOnSellerCoupon().add(
						order.getTotalProductPriceInSellerCoupon());
				
				group.getOrders().add(order);
			}// end orders

			// 分摊商家优惠活动金额
			apportionSellerPromotions(group);
			
			// 计算区域折扣到订单
			calcRegionDiscountToOrder(group, currency);

			// 分摊区域折扣到订单项
			apportionRegionDiscountToOrderItem(group, currency);

			int index = 0;
			
			for (CouponVo sCoupon : sellerCoupons) {
				if (sCoupon != null) {
					if (isCDFCoupon) {

						List<OrderItem> orderItemList = new ArrayList<>();
						List<OrderVoForCdfCoupon> orderVoList = new ArrayList<>();

						for (Order order : group.getOrders()) {

							OrderVoForCdfCoupon orderVoForCdfCoupon = new OrderVoForCdfCoupon();

							List<ProductVoForCdfCoupon> productVoList = new ArrayList<>();

							for (OrderItem orderItem : order.getOrderItems()) {

								ProductVoForCdfCoupon productVoForCdfCoupon = new ProductVoForCdfCoupon();

								OrderItemVo orderItemVo = orderItem.getItemVo();

								BigDecimal productPriceExcludeSellerPromotionAndRegionDiscount = orderItemVo
										.getProductPrice()
										.multiply(
												new BigDecimal(orderItemVo
														.getProductNum()))
										.subtract(
												Utils.zeroIfNull(orderItem
														.getSellerPromotionAmount()))
										.subtract(
												Utils.zeroIfNull(orderItem
														.getRegionDiscountValue()))
										.divide(new BigDecimal(
												orderItemVo.getProductNum()),
												2, BigDecimal.ROUND_DOWN);

								productVoForCdfCoupon.setCatalogId(orderItemVo
										.getCatalogId());
								productVoForCdfCoupon
										.setPrice(productPriceExcludeSellerPromotionAndRegionDiscount);
								productVoForCdfCoupon.setProductId(orderItemVo
										.getProductId());
								productVoForCdfCoupon.setProductNum(orderItemVo
										.getProductNum());
								productVoForCdfCoupon.setSkuId(orderItemVo
										.getSku());
								productVoForCdfCoupon.setSubProduct(orderItemVo
										.isSubProduct());
								productVoForCdfCoupon
										.setExchangeBuy(orderItemVo
												.getExchangeBuy());

								productVoList.add(productVoForCdfCoupon);

								orderItemList.add(orderItem);
							}

							orderVoForCdfCoupon.setProductVoList(productVoList);

							orderVoList.add(orderVoForCdfCoupon);
						}

						CdfDeductCouponBeforePlaceReq cdfDeductCouponBeforePlaceReq = new CdfDeductCouponBeforePlaceReq();

						// 领取cdf优惠券
						CDFMemberService.getCdfCoupon(groupVo.getSellerCoupon()
								.getCouponType(),
								groupVo.getSellerId() == 502665591 ? 2 : 1,
								placeOrderReq.getUserId());

						groupVo.getSellerCoupon().setCouponCode(
								CDFMemberService.getLatestUnuseCdfCoupon(
										placeOrderReq.getUserId(),
										groupVo.getSellerId()));

						cdfDeductCouponBeforePlaceReq.setCouponVo(groupVo
								.getSellerCoupon());
						cdfDeductCouponBeforePlaceReq.setSellerId(groupVo
								.getSellerId());
						cdfDeductCouponBeforePlaceReq.setUserId(placeOrderReq
								.getUserId());
						cdfDeductCouponBeforePlaceReq
								.setOrderVoList(orderVoList);

						CdfDeductCouponBeforePlaceResp cdfDeductCouponBeforePlaceResp = SqTradingCallService
								.cdfDeductCouponBeforePlace(cdfDeductCouponBeforePlaceReq);

						// 分摊中免优惠券到订单项
						apportionCDFCouponToOrderItem(orderItemList,
								cdfDeductCouponBeforePlaceResp
										.getCouponAmountVoList());

						for (Order order : group.getOrders()) {

							BigDecimal orderCouponValue = order.getOrderItems()
									.stream()
									.map(o -> o.getSellerCouponValue())
									.reduce(BigDecimal.ZERO, BigDecimal::add);
							order.setSellerCouponValue(orderCouponValue);
						}
					} else {

						if (sCoupon.getCouponType() == 5) {

						} else {
	
							// 分摊商家优惠券
							if (totalProductPriceInSellerCoupon
									.compareTo(sellerCoupon.getCouponValue()) <= 0) {
								throw new IllegalArgumentException(
										"商家适用优惠券的商品成交价总额必须大于商家优惠券总额:"
												+ groupVo.getSellerId());
							}
						}

						// 分摊商家优惠券到订单
						apportionSellerCouponToOrder(group, currency, sCoupon, index);

						// 分摊商家优惠券到订单项
						DGSQPlaceOrderVerifyService.apportionSellerCouponToOrderItem(group, currency, index);
						
						totalProductPriceInSellerCoupon = totalProductPriceInSellerCoupon.subtract(sCoupon.getCouponValue());
					}
					
					index = index + 1;
				}
			}
		}// end groups

		List<BigDecimal> productPriceWeights = new ArrayList<BigDecimal>();

		// 分摊折扣
		if (placeOrderReq.getDiscount() != null) {
			
			for (Order order : allOrders) {
				
				productPriceWeights.add(order.getTotalProductPrice());
				
				if (order.getIsProxy()) {
					
					orderWeightsDiscount.add(order.getOrderGrossProfit());
				} else {
					
					orderWeightsDiscount.add(order.getTotalProductPrice());
				}
			}
			
			// 如果代理订单没有利润
			if (orderWeightsDiscount.stream().reduce(BigDecimal::add)
					.orElse(BigDecimal.ZERO).compareTo(BigDecimal.ZERO) <= 0) {
				
				orderWeightsDiscount = productPriceWeights;
			}

			boolean isNegate = placeOrderReq.getDiscount().
					compareTo(BigDecimal.ZERO) == -1 ? true : false;

			DGSQPlaceOrderVerifyService.apportionOrderDiscountToOrder(allOrders,
					placeOrderReq.getDiscount(), orderWeightsDiscount,
					currency, isNegate);

			DGSQPlaceOrderVerifyService.apportionOrderDiscountToOrderItem(allOrders, currency, isNegate);
		}
		
		calcExpectedOrderTaxFee(allOrders, placeOrderReq.getAddress());
		
		// 分摊积分，经讨论，先摊积分抵扣金额，再将金额换算成积分
		if (placeOrderReq.getIntegral() != null) {

			Long shopId = placeOrderReq.getOrderGroups().get(0).getSellerId();
			
			// 中免大会员使用积分，不关心分摊
			if (isCDFMember(shopId)) {
				return mainOrder;
			} else {
				
				// 使用的积分超过限额时，无法下单；这里只需要获取积分策略，计算下单使用的积分抵扣金额
				CalcOrderCreditResp calcOrderCreditResp = GodPointsService
						.calcOrderCredit(new BigDecimal("0.01"),
								Utils.nullIsCNY(currency), shopId,
								placeOrderReq.getUserId());

				BigDecimal integralAmount = GodPointsService.calcOrderCreditAmount(
						calcOrderCreditResp, placeOrderReq.getIntegral());

				for (Order order : allOrders) {
					
					BigDecimal orderNetProfitWeight = BigDecimal.ZERO;
					
					for (OrderItem orderItem : order.getOrderItems()) {
						
						BigDecimal orderItemNetProfit = BigDecimal.ZERO;
						BigDecimal orderItemNetProfitWeight = BigDecimal.ZERO;
											
						if (order.getGoodsOwnerId() != order.getSellerId()) {

							BigDecimal freight = Utils.falseIfNull(orderItem.getItemVo()
									.getFullReductionFreeFreight()) ? orderItem.getItemVo().getFreight().negate()
									: BigDecimal.ZERO;
							
							// 店主的商品纯利润
							orderItemNetProfit = orderItem
									.getOrderItemGrossProfit()
									.add(Utils.zeroIfNull(orderItem
											.getDiscount()))
									.add(Utils.zeroIfNull(freight))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getSellerCouponValue()))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getSellerPromotionAmount()))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getYmatouCouponValue()))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getRegionDiscountValue()));
						} else {

							BigDecimal freight = Utils.falseIfNull(orderItem.getItemVo()
									.getFullReductionFreeFreight()) ? BigDecimal.ZERO
									: orderItem.getItemVo().getFreight();
							
							// 店主的商品纯利润
							orderItemNetProfit = orderItem
									.getOrderItemGrossProfit()
									.add(Utils.zeroIfNull(freight))
									.add(Utils.zeroIfNull(orderItem
											.getDiscount()))
									.add(Utils.zeroIfNull(orderItem.getTaxFee()))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getSellerCouponValue()))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getSellerPromotionAmount()))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getYmatouCouponValue()))
									.subtract(
											Utils.zeroIfNull(orderItem
													.getRegionDiscountValue()));
						}
						
						if (orderItemNetProfit.compareTo(BigDecimal.ZERO) == 1)
							orderItemNetProfitWeight = orderItemNetProfit;
									
						order.getOrderItemWeightsOnIntegralDeduction().add(orderItemNetProfitWeight);
					}
				
					// 订单纯利润
					BigDecimal orderNetProfit = order.getOrderItems().stream()
							.map(OrderItem::getOrderItemGrossProfit)
							.reduce(BigDecimal.ZERO, BigDecimal::add);
					
					if (orderNetProfit.compareTo(BigDecimal.ZERO) == 1)
						orderNetProfitWeight = orderNetProfit;
					
					orderWeightsIntegralDeduction.add(orderNetProfitWeight);
				}
				
				// 各订单分摊积分抵扣金额的权重
				List<BigDecimal> orderWeightsIntegral = DGSQPlaceOrderVerifyService.apportionOrderIntegralDeductionToOrder(allOrders, integralAmount,
						orderWeightsIntegralDeduction, currency);
				DGSQPlaceOrderVerifyService.apportionOrderIntegralDeductionToOrderItem(allOrders, currency);

				DGSQPlaceOrderVerifyService.apportionOrderIntegralToOrder(allOrders, new BigDecimal(
						placeOrderReq.getIntegral()), orderWeightsIntegral);
				DGSQPlaceOrderVerifyService.apportionOrderIntegralToOrderItem(allOrders);
			}
		}

		return mainOrder;
	}

	/**
	 * 分摊商家优惠券到订单
	 */
	private static void apportionSellerCouponToOrder(OrderGroup g,
			String currency, CouponVo sellerCouponVo, int index) {
		
		Logger.comment(String.format("分摊第%s张优惠券到订单", index + 1));
		
		if (sellerCouponVo.getCouponType() == 5) {

			BigDecimal[] couponValues = g.getOrderWeightsOnSellerCoupon()
					.toArray(new BigDecimal[0]);

			for (int i = 0; i < couponValues.length; i++) {

				g.getOrders().get(i).setSellerCouponValue(couponValues[i]);

				OrderCouponDetailPo orderCouponDetailPo = new OrderCouponDetailPo();

				orderCouponDetailPo.setCouponCode(sellerCouponVo
						.getCouponCode());
				orderCouponDetailPo.setCouponSource(sellerCouponVo
						.getCouponSource());
				orderCouponDetailPo.setCouponType(5);
				orderCouponDetailPo.setDeleted(false);
				orderCouponDetailPo.setAmount(couponValues[i]);

				g.getOrders()
						.get(i)
						.setOrderCouponDetailList(
								Arrays.asList(orderCouponDetailPo));
			}
		} else {

			BigDecimal[] result = Utils.apportionByWeights3(sellerCouponVo
					.getCouponValue(), g.getOrderWeightsOnSellerCoupon()
					.toArray(new BigDecimal[0]), currency);
			
			List<BigDecimal> newOrderWeightsOnSellerCoupon = new ArrayList<>();

			for (int i = 0; i < result.length; i++) {
				
				g.getOrders()
						.get(i)
						.setSellerCouponValue(
								Utils.zeroIfNull(
										g.getOrders().get(i)
												.getSellerCouponValue()).add(
										result[i]));
				
				OrderCouponDetailPo orderCouponDetailPo = new OrderCouponDetailPo();

				orderCouponDetailPo.setCouponCode(sellerCouponVo
						.getCouponCode());
				orderCouponDetailPo.setCouponSource(sellerCouponVo
						.getCouponSource());
				orderCouponDetailPo.setCouponType(sellerCouponVo.getCouponType());
				orderCouponDetailPo.setDeleted(false);
				orderCouponDetailPo.setAmount(result[i]);

				if (null == g.getOrders().get(i).getOrderCouponDetailList()) {

					g.getOrders()
							.get(i)
							.setOrderCouponDetailList(
									Arrays.asList(orderCouponDetailPo));
				} else {

					List<OrderCouponDetailPo> details = new ArrayList<>(g
							.getOrders().get(i).getOrderCouponDetailList());

					details.add(orderCouponDetailPo);

					g.getOrders().get(i).setOrderCouponDetailList(details);
				}
				
				newOrderWeightsOnSellerCoupon.add(g
						.getOrderWeightsOnSellerCoupon().get(i)
						.subtract(result[i]));
			}
			
			g.setOrderWeightsOnSellerCoupon(newOrderWeightsOnSellerCoupon);
		}
	}

	
	/**
	 * 分摊商家优惠
	 *
	 * @param group
	 */
	private static void apportionSellerPromotions(OrderGroup group) {
		if (!CollectionUtils.isEmpty(group.getOrderGroupVo()
				.getSellerPromotionApportions())) {
			group.distributeSellerPromotionApportions();
		}
	}
	
	/**
	 * 计算区域折扣到订单
	 */
	private void calcRegionDiscountToOrder(OrderGroup g,
			String currency) {
		
		int scale = 0;
		
		if (null == placeOrderReq.getCurrency())
			scale = 2;
		else if (null != placeOrderReq.getCurrency()
				&& placeOrderReq.getCurrency().equalsIgnoreCase(
						"JPY"))
			scale = 0;
		
		// 订单上区域折扣权重
		for (Order order : g.getOrders()) {

			BigDecimal regionDiscount = BigDecimal.ZERO;
			
			// 区域折扣金额
			if (Utils.zeroIfNull(order.getOrderVo().getRegionDiscountRatio()).compareTo(BigDecimal.ZERO) == 1) {
							
				
				BigDecimal regionDiscountRate = BigDecimal.ONE.subtract(Utils
						.zeroIfNull(order.getOrderVo().getRegionDiscountRatio()).divide(
								BigDecimal.TEN, 2, BigDecimal.ROUND_DOWN));
				
				regionDiscount = order.getTotalProductPrice()
						.subtract(order.getSellerPromotionAmount())
						.multiply(regionDiscountRate).setScale(scale, BigDecimal.ROUND_DOWN);
				
				order.setRegionDiscountValue(regionDiscount);
			} else
				order.setRegionDiscountValue(regionDiscount);
		}
	}

	/**
	 * 分摊区域折扣到订单商品
	 * 
	 * @param g
	 */
	private static void apportionRegionDiscountToOrderItem(OrderGroup g,
			String currency) {

		for (Order order : g.getOrders()) {
			
			// 订单项上区域折扣权重
			for (OrderItem orderItem : order.getOrderItems()) {

				order.getOrderItemWeightsOnRegionDiscount()
						.add(orderItem
								.getItemVo()
								.getProductPrice()
								.multiply(
										new BigDecimal(orderItem.getItemVo()
												.getProductNum()))
								.subtract(orderItem.getSellerPromotionAmount()));
			}
			
			if (Utils.zeroIfNull(order.getRegionDiscountValue()).compareTo(BigDecimal.ZERO) == 1) {
				BigDecimal[] result = Utils.apportionByWeights3(
						order.getRegionDiscountValue(),
						order.getOrderItemWeightsOnRegionDiscount().toArray(
								new BigDecimal[0]), currency);
				for (int i = 0; i < result.length; i++) {
					order.getOrderItems().get(i)
							.setRegionDiscountValue(result[i]);
				}
			}
		}
	}

	/**
	 * 分摊CDF优惠券到订单商品
	 * 
	 * @param
	 */
	private static void apportionCDFCouponToOrderItem(
			List<OrderItem> orderItemList, List<CouponAmountVo> couponAmountList) {

		for (int i = 0; i < couponAmountList.size(); i++) {

			orderItemList.get(i).setSellerCouponValue(
					couponAmountList.get(i).getDeductionAmount());
		}
	}
	
	private void calcExpectedOrderTaxFee(List<Order> orders,
			String address) {

		int scale = 0;

		for (Order o : orders) {

			BigDecimal orderTaxFee = BigDecimal.ZERO;
			BigDecimal productTaxFee = BigDecimal.ZERO;

			for (OrderItem orderItem : o.getOrderItems()) {

				if (SqTradingCallService.isFreePerimeters(placeOrderReq
						.getAddress()))
					productTaxFee = BigDecimal.ZERO;
				else {

					if (null == placeOrderReq.getCurrency())
						scale = 2;
					else if (null != placeOrderReq.getCurrency()
							&& placeOrderReq.getCurrency().equalsIgnoreCase(
									"JPY"))
						scale = 0;

					boolean fullReductionFreeFreight = Utils
							.falseIfNull(orderItem.getItemVo()
									.getFullReductionFreeFreight());

					productTaxFee = Utils
							.zeroIfNull(
									fullReductionFreeFreight ? BigDecimal.ZERO
											: orderItem.getItemVo()
													.getFreight())
							.divide(new BigDecimal(orderItem.getItemVo()
									.getProductNum()), 32, RoundingMode.DOWN)
							.add(orderItem.getItemVo().getProductPrice())
							.add(Utils.zeroIfNull(orderItem.getDiscount())
									.divide(new BigDecimal(orderItem
											.getItemVo().getProductNum()), 32,
											RoundingMode.DOWN))
							.subtract(
									Utils.zeroIfNull(
											orderItem.getSellerCouponValue())
											.divide(new BigDecimal(orderItem
													.getItemVo()
													.getProductNum()), 32,
													RoundingMode.DOWN))
							.subtract(
									Utils.zeroIfNull(orderItem
											.getYmatouCouponValue()))
							.subtract(
									Utils.zeroIfNull(
											orderItem
													.getSellerPromotionAmount())
											.divide(new BigDecimal(orderItem
													.getItemVo()
													.getProductNum()), 32,
													RoundingMode.DOWN))
							.subtract(
									Utils.zeroIfNull(orderItem.getItemVo()
											.getYmtPromotionAmount()))
							.subtract(
									Utils.zeroIfNull(orderItem
											.getRegionDiscountValue()))
							.multiply(
									Utils.zeroIfNull(orderItem.getItemVo()
											.getProdTaxRate()))
							.setScale(scale, RoundingMode.HALF_UP);
					
					BigDecimal orderItemTaxFee = productTaxFee
							.multiply(new BigDecimal(orderItem.getItemVo()
									.getProductNum()));
					
					orderItem.setTaxFee(orderItemTaxFee);

					orderTaxFee = orderTaxFee.add(orderItemTaxFee);
				}
			}

			o.setTaxFee(orderTaxFee);
		}
	}
	
	private static BigDecimal calActualOrderTaxFee(
			List<OrderDetailPo> orderDetails) {

		BigDecimal taxFee = BigDecimal.ZERO;

		for (OrderDetailPo detailPo : orderDetails) {

			taxFee = taxFee.add(detailPo.getTaxFee().multiply(
					new BigDecimal(detailPo.getProductCount())));
		}

		return taxFee;
	}
	
	private static Boolean isCDFMember(Long shopId) {

		return SqTradingCallService.isCDFMember(shopId);
	}

	private void verify(List<PlaceOrderReq> bookingPlaceOrderReqList) throws Exception {

		verify(bookingPlaceOrderReqList, false);
	}

	/**
	 * 
	 * @param bookingPlaceOrderReqList
	 * @param isVerificationPreStock 预售库存是否添加库存核销
	 * @throws Exception
	 */
	private void verify(List<PlaceOrderReq> bookingPlaceOrderReqList, boolean isVerificationPreStock) throws Exception {

		Logger.verifyEquals(ECode.SUCCESS, placeorderCall.getString("code"),
				"验证code");

		Logger.verifyEquals("0", placeorderCall.getString("bcode"), "验证bcode");

		PlaceOrderResp orderResp = placeorderCall.getPlaceOrderResp();

		Logger.verifyEquals(true, orderResp.getSuccess(), "验证success");

		if (!orderResp.getSuccess()) {

			Logger.fail(new RuntimeException("!!!!!!!!!下单失败！"));
		}

		long mainOrderId = placeOrderReq.getMainOrderId();

		// 校验主单表(main_order)
		verifyService.verifyMainOrderDb(mainOrderId, placeOrderReq.getProxyOrderId(), placeOrderReq.getPayDeductAmount(), placeOrderReq.getIntegral());

		List<Long> orderIds = orderResp.getOrderIds();

		MainOrder mainOrder = buildOrder(bookingPlaceOrderReqList);

		List<Order> orders = new ArrayList<Order>();

		for (OrderGroup orderGroup : mainOrder.getOrderGroups())
			orderGroup.getOrders().forEach(temp -> orders.add(temp));
		
		Long sellerId = 0L;

		for (int i = 0; i < orderIds.size(); i++) {

			long orderId = orderIds.get(i);

			Order expectedOrder = orders.get(i);
			
			Boolean isLiveOrder = DGSQPlaceOrderVerifyService.isLiveOrder(expectedOrder.getOrderItems(),
					orderId);

			OrderPo actualOrder = orderShardingWapper
					.selectOrderbyOrderId(orderIds.get(i));

			// 校验订单表(order)
			verifyOrderDb(expectedOrder, actualOrder, isVerificationPreStock);
			
			// 直播订单校验
			Logger.verifyEquals(isLiveOrder, actualOrder.getLiveOrder(),
					"验证数据库LiveOrder");

			// 校验订单扩展表(order_ext)
			verifyOrderExtDb(expectedOrder, orderId);

			List<OrderItem> expectedOrderDetails = expectedOrder
					.getOrderItems();

			List<OrderDetailPo> actualOrderDetails = orderShardingWapper
					.selectOrderDetailbyOrderId(orderId);

			BigDecimal orderTotalPrice = actualOrderDetails
					.stream()
					.map(detail -> detail.getProductPrice().multiply(
							new BigDecimal(detail.getProductCount())))
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			BigDecimal orderFreight = actualOrderDetails
					.stream()
					.filter(detail -> Utils.falseIfNull(detail
							.getFullReductionFreeFreight()) == false)
					.map(detail -> detail.getFreight())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			BigDecimal orderYmtCouponAmount = actualOrderDetails.stream()
					.map(detail -> detail.getYmtCouponAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			BigDecimal orderSellerCouponAmount = actualOrderDetails.stream()
					.map(detail -> detail.getSellerCouponAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			BigDecimal orderServiceAmount = actualOrderDetails.stream()
					.map(detail -> detail.getServiceAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			
			BigDecimal payableAmount = actualOrderDetails.stream()
					.map(detail -> detail.getPayableAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			
			BigDecimal orderRegionDiscountAmount = actualOrderDetails.stream()
					.map(detail -> detail.getRegionDiscountAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			
			if (isCDFMember(actualOrder.getSellerId())) {
				
				Long orderIntegral = actualOrderDetails.stream()
						.filter(detail -> null != detail.getIntegral())
						.mapToLong(OrderDetailPo::getIntegral).sum();
				
				DataUtil.verifyDecimalEquals(actualOrder.getIntegral(),
						orderIntegral, "验证数据库订单上的orderIntegral为该订单所有商品总积分之和");
			}
			
			// 计算订单的taxFee
			BigDecimal taxFee = calActualOrderTaxFee(actualOrderDetails);

			DataUtil.verifyDecimalEquals(actualOrder.getTotalPrice(),
					orderTotalPrice, "验证数据库订单上的TotalPrice为该订单所有商品总价之和");

			DataUtil.verifyDecimalEquals(actualOrder.getFreight(),
					orderFreight, "验证数据库订单上的Freight为该订单所有商品运费之和");

			DataUtil.verifyDecimalEquals(actualOrder.getYmtCouponAmount(),
					orderYmtCouponAmount,
					"验证数据库订单上的总YmatouCouponValue为该订单所有商品平台券之和");

			DataUtil.verifyDecimalEquals(actualOrder.getSellerCouponAmount(),
					orderSellerCouponAmount,
					"验证数据库订单上的总orderSellerCouponAmount为该订单所有商品商家券之和");

			DataUtil.verifyDecimalEquals(taxFee, actualOrder.getTaxFee(),
					"验证数据库订单上的总TaxFee为该订单所有商品税费之和");

			DataUtil.verifyDecimalEquals(orderServiceAmount,
					actualOrder.getServiceAmount(),
					"验证数据库订单上的总serviceAmount为该订单所有商品服务费之和");
			
			DataUtil.verifyDecimalEquals(payableAmount,
					actualOrder.getPayableAmount(),
					"验证数据库订单上的总payableAmount为该订单所有商品可支付金额之和");
			
			DataUtil.verifyDecimalEquals(orderRegionDiscountAmount,
					actualOrder.getRegionDiscountAmount(),
					"验证数据库订单上的总RegionDiscountAmount为该订单所有商品区域折扣之和");

			if (placeOrderReq.getBizSource() != null) {

				BizVo expectedBiz = placeOrderReq.getBizSource();

				OrderBizPo actualOrderBiz = orderShardingWapper
						.selectOrderBizbyOrderId(orderId);

				// 校验订单业务来源表order_biz
				verifyService.verifyOrderBizDb(expectedBiz, actualOrderBiz);
			}
			
			// 校验order_biz_log
			verifyService.verifyOrderBizLogDb(orderId, placeOrderReq.getShenqiBuyOrderCsId());

			// 校验订单商品表(order_detail)
			verifyOrderDetailDb(expectedOrderDetails, actualOrderDetails,
					expectedOrder, actualOrder.getGoodsOwnerId(), Utils.falseIfNull(actualOrder.getWaitInStock()));

			verifyService.verifyShenqiSellerProfit(actualOrder, actualOrderDetails, expectedOrder.getIsInherited(),
					expectedOrderDetails.get(0).getShenqiProxyChain());

			if (placeOrderReq.getTravelerVos() != null
					&& placeOrderReq.getTravelerVos().size() != 0) {

				verifyService.verifyOrderTraveler(placeOrderReq.getTravelerVos(),
						orderId, actualOrder.getUserId(),
						actualOrder.getSellerId());
			}
			
			sellerId = actualOrder.getOrderId();
		}
		
		if (isCDFMember(sellerId)) {
			
			List<OrderPo> actualOrders = orderShardingWapper.selectOrderbyMainOrderId(mainOrderId);
			
			Long orderIntegral = actualOrders.stream()
					.filter(detail -> null != detail.getIntegral())
					.mapToLong(OrderPo::getIntegral).sum();
			
			DataUtil.verifyDecimalEquals(placeOrderReq.getIntegral(),
					orderIntegral, "验证数据库订单上的orderIntegral为该订单所有总积分之和");
		}
	}
	
	/**
	 * 校验订单表(order)
	 * 
	 * @param expectedOrder
	 * @param actualOrder
	 */
	private void verifyOrderDb(Order expectedOrder, OrderPo actualOrder, boolean isVerificationPreStock) {

		Logger.comment(String.format("校验订单表(order) orderId:%s",
				actualOrder.getOrderId()));

		Logger.verifyEquals(placeOrderReq.getMainOrderId(),
				actualOrder.getMainOrderId(), "验证数据库MainOrderId");

		Logger.verifyEquals(expectedOrder.getSellerId(),
				actualOrder.getSellerId(), "验证数据库SellerId");
		DataUtil.verifyDecimalEquals(expectedOrder.getFreight(),
				actualOrder.getFreight(), "验证数据库Freight");

		BigDecimal productEarnestAmount = BigDecimal.ZERO;
		BigDecimal bookingPromotionAmount = BigDecimal.ZERO;

		List<OrderItemVo> orderItems = expectedOrder.getOrderVo()
				.getOrderItems();

		for (OrderItemVo orderItem : orderItems) {

			if (null != orderItem.getBookingPromotionAmount())
				bookingPromotionAmount = orderItem.getBookingPromotionAmount()
						.multiply(new BigDecimal(orderItem.getProductNum()))
						.add(bookingPromotionAmount);

			if (null != orderItem.getEarnestAmount())
				productEarnestAmount = orderItem.getEarnestAmount()
						.multiply(new BigDecimal(orderItem.getProductNum()))
						.add(productEarnestAmount);
		}

		if (productEarnestAmount.compareTo(BigDecimal.ZERO) != 0)
			DataUtil.verifyDecimalEquals(productEarnestAmount,
					actualOrder.getEarnestAmount(), "验证数据库EarnestAmount");
		else
			DataUtil.verifyDecimalEquals(null, actualOrder.getEarnestAmount(),
					"验证数据库EarnestAmount");

		if (bookingPromotionAmount.compareTo(BigDecimal.ZERO) != 0)
			DataUtil.verifyDecimalEquals(bookingPromotionAmount,
					actualOrder.getBookingPromotionAmount(),
					"验证数据库BookingPromotionAmount");
		else
			DataUtil.verifyDecimalEquals(null,
					actualOrder.getBookingPromotionAmount(),
					"验证数据库BookingPromotionAmount");

		DataUtil.verifyDecimalEquals(expectedOrder.getOrderVo()
				.getEarnestCardAmount(), actualOrder.getEarnestCardAmount(),
				"验证数据库EarnestCardAmount");
		DataUtil.verifyDateEquals(expectedOrder.getOrderVo()
				.getPaymentStartTime(), actualOrder.getPaymentStartTime(),
				"验证数据库PaymentStartTime");
		DataUtil.verifyDateEquals(expectedOrder.getOrderVo()
				.getPaymentEndTime(), actualOrder.getPaymentEndTime(),
				"验证数据库PaymentEndTime");
		Logger.verifyEquals(false, actualOrder.getCanConfirm(),
				"验证数据库CanConfirm");
		
		DataUtil.verifyDecimalEquals(expectedOrder.getTaxFee(),
				actualOrder.getTaxFee(), "验证数据库TaxFee");
		
		BigDecimal excludeIntegralPayableAmount = actualOrder
				.getTotalPrice()
				.add(Utils.zeroIfNull(actualOrder.getFreight()))
				.add(Utils.zeroIfNull(actualOrder.getOrderDiscount()))
				.add(Utils.zeroIfNull(actualOrder.getTaxFee()))
				.add(Utils.zeroIfNull(actualOrder.getServiceAmount()))
				.subtract(Utils.zeroIfNull(actualOrder.getYmtCouponAmount()))
				.subtract(Utils.zeroIfNull(actualOrder.getSellerCouponAmount()))
				.subtract(Utils.zeroIfNull(actualOrder.getPromotionAmount()))
				.subtract(Utils.zeroIfNull(actualOrder.getYmtPromotionAmount()))
				.subtract(Utils.zeroIfNull(actualOrder.getRegionDiscountAmount()));
		
		BigDecimal payableAmount = excludeIntegralPayableAmount.subtract(Utils
				.zeroIfNull(actualOrder.getIntegralDeductionAmount()));

		Logger.verifyEquals(expectedOrder.getOrderVo().getLogisticsType()
				.getCode(), actualOrder.getLogisticsType(),
				"验证数据库LogisticsType");
		Logger.verifyEquals(1, actualOrder.getOrderStatus(), "验证数据库OrderStatus");
		Logger.verifyEquals(null, actualOrder.getPaymentId(), "验证数据库PaymentId");
		DataUtil.verifyDecimalEquals(expectedOrder.getTotalProductPrice(),
				actualOrder.getTotalPrice(), "验证数据库TotalPrice");

		DataUtil.verifyDecimalEquals(expectedOrder.getOrderDiscount(),
				actualOrder.getOrderDiscount(), "验证数据库OrderDiscount");

		Logger.verifyEquals(expectedOrder.getYmatouCouponCode(),
				actualOrder.getYmtCouponCode(), "验证数据库YmtCouponCode");

		DataUtil.verifyDecimalEquals(expectedOrder.getYmatouCouponValue(),
				actualOrder.getYmtCouponAmount(), "验证数据库YmtCouponAmount");

		DataUtil.verifyDecimalEquals(expectedOrder.getSellerPromotionAmount(),
				actualOrder.getPromotionAmount(), "验证数据库PromotionAmount");

		Logger.verifyEquals(expectedOrder.getSellerCouponCode(),
				actualOrder.getSellerCouponCode(), "验证数据库SellerCouponCode");

		DataUtil.verifyDecimalEquals(expectedOrder.getSellerCouponValue(),
				actualOrder.getSellerCouponAmount(), "验证数据库SellerCouponAmount");
		
		if (null == expectedOrder.getOrderCouponDetailList())
			Logger.comment("该订单没有使用优惠券");
		else
			verifyService.verifyOrderCouponDetail(expectedOrder.getOrderCouponDetailList(),
					actualOrder.getOrderId(), placeOrderReq.getMainOrderId());

		DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
				actualOrder.getAccountPaidAmount(), "验证数据库AccountPaidAmount");
		DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
				actualOrder.getThirdpartyPaidAmount(),
				"验证数据库ThirdpartyPaidAmount");

		DataUtil.verifyDecimalEquals(expectedOrder.getCardAmount(),
				actualOrder.getCardAmount(), "验证数据库cardAmount");

		Logger.verifyEquals(placeOrderReq.getAddressId(),
				actualOrder.getAddressId(), "验证数据库AddressId");

		Logger.verifyEquals(null, actualOrder.getPaidTime(), "验证数据库PaidTime");
		Logger.verifyEquals(null, actualOrder.getAcceptTime(),
				"验证数据库AcceptTime");
		Logger.verifyEquals(null, actualOrder.getDeliveryTime(),
				"验证数据库DeliveryTime");
		Logger.verifyEquals(null, actualOrder.getReceiveTime(),
				"验证数据库ReceiveTime");
		Logger.verifyEquals(null, actualOrder.getCancelTime(),
				"验证数据库CancelTime");

		Logger.verifyEquals(false, actualOrder.getXloboDelivery(),
				"验证数据库XloboDelivery");
		Logger.verifyEquals(expectedOrder.containsPreSalePrds(),
				actualOrder.getPresale(), "验证数据库Presale");

		Logger.verifyEquals(RiskControlStatusEnum.Unknown.getCode(),
				actualOrder.getRiskStatus(), "验证数据库RiskStatus");

		Logger.verifyEquals(0, actualOrder.getOrderStatusMemo(),
				"验证数据库orderStatusMemo");

		Logger.verifyEquals(false, actualOrder.getLocked(), "验证数据库Locked");
		Logger.verifyEquals(false, actualOrder.getDeleted(), "验证数据库Deleted");

		Logger.verifyEquals(null, actualOrder.getCancelReason(),
				"验证数据库CancelReason");

		Logger.info("时间差为 :" + Utils.calcTimeSpanMin(actualOrder.getAddTime()));
		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actualOrder.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actualOrder.getAddTime()) < 2,
				"验证数据库UpdateTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(expectedOrder.getSellerCouponCode(),
				actualOrder.getSellerCouponCode(), "验证数据库SellerCouponCode");
		Logger.verifyEquals(0, actualOrder.getOrderStatusMemo(),
				"验证数据库OrderStatusMemo");

		Logger.verifyEquals(placeOrderReq.getUserId(), actualOrder.getUserId(),
				"验证数据库UserId");
		DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
				actualOrder.getThirdpartyDiscount(), "验证数据库ThirdpartyDiscount");
		DataUtil.verifyDecimalEquals(expectedOrder.getOrderVo()
				.getAutoCancelOrderHours(), actualOrder.getAutoCancelHour(),
				"验证数据库AutoCancelHour");
		Logger.verifyEquals(false, actualOrder.getDomesticDelivery(),
				"验证数据库DomesticDelivery");

		Logger.verifyEquals(null, actualOrder.getNewCustomer(),
				"验证数据库NewCustomer");
		Logger.verifyEquals(null, actualOrder.getNewSeller(), "验证数据库NewSeller");

		Logger.verifyEquals(expectedOrder.getOrderVo().isEcommerceFlag(),
				actualOrder.getPredictEcommerce(), "验证数据库PredictEcommerce");

		Logger.verifyEquals(null, actualOrder.getActualEcommerce(),
				"验证数据库ActualEcommerce");
		
		Logger.verifyEquals(expectedOrder.getGoodsOwnerId(),
				actualOrder.getGoodsOwnerId(), "验证数据库GoodsOwnerId");

		Logger.verifyEquals(expectedOrder.getSalesman(),
				actualOrder.getSalesman(), "验证数据库Salesman");

		Logger.verifyEquals(expectedOrder.getShenqiLogisticsType(),
				actualOrder.getShenqiLogisticsType(),
				"验证数据库ShenqiLogisticsType");
		Logger.verifyEquals(expectedOrder.getCurrency(),
				actualOrder.getCurrency(), "验证数据库currency");
		Logger.verifyEquals(expectedOrder.getCurrencySymbol(),
				actualOrder.getCurrencySymbol(), "验证数据库currencySymbol");
		Logger.verifyEquals(
				expectedOrder.getOrderVo().getPackageDeliveryType(),
				actualOrder.getPackageDeliveryType(),
				"验证数据库packageDeliveryType");

		Logger.verifyEquals(false, actualOrder.getSupportOfflinePay(),
				"验证数据库supportOfflinePay");

		Logger.verifyEquals(
				Utils.falseIfNull(placeOrderReq.getShenqiProxyBuyOrder()),
				actualOrder.getShenqiProxyBuyOrder(),
				"验证数据库ShenqiProxyBuyorder");

		Logger.verifyEquals(placeOrderReq.getCustomSettlementCurrencyType(),
				actualOrder.getCustomSettlementCurrencyType(),
				"验证数据库CustomSettlementCurrencyType");

		Logger.verifyEquals(expectedOrder.getOrderVo().getOrderAlias(),
				actualOrder.getOrderAlias(), "验证数据库OrderAlias");

		Logger.verifyEquals(placeOrderReq.getPayChannelType(),
				actualOrder.getPayChannelType(), "验证数据库PayChannelType");

		Logger.verifyEquals(
				Utils.falseIfNull(placeOrderReq.getPickupInStores()),
				actualOrder.getPickupInStores(), "验证数据库PickupInStores");

		Logger.verifyEquals(expectedOrder.getShenqiIdCardRequirement(),
				actualOrder.getShenqiIdcardRequirement(),
				"验证数据库ShenqiIdcardRequirement");
		
		Logger.verifyEquals(expectedOrder.getOrderVo().getPurchaserIdcardId(),
				actualOrder.getPurchaserIdcardId(), "验证数据库PurchaserIdcardId");

		Logger.verifyEquals(
				Utils.falseIfNull(placeOrderReq.getPickupInStores()) == true ? false
						: expectedOrder.getShenqiIdCardRequirement() > 0,
				actualOrder.getNeedUploadIdcard(), "验证数据库NeedUploadIdcard");

		if (null != productEarnestAmount
				&& productEarnestAmount.compareTo(BigDecimal.ZERO) == 1
				&& null == actualOrder.getEarnestPaidTime())
			DataUtil.verifyDecimalEquals(actualOrder.getEarnestAmount(),
					actualOrder.getPayableAmount(), "验证数据库PayableAmount");
		else
			DataUtil.verifyDecimalEquals(payableAmount,
					actualOrder.getPayableAmount(), "验证数据库PayableAmount");

		Logger.verifyEquals(expectedOrder.getOrderVo().getWarehouseId(),
				actualOrder.getWarehouseId(), "验证数据库WarehouseId");

		boolean waitInStock = false;

		// 预售订单，预售活动如果使用了虚拟库存，则为true
		for (OrderItemVo orderItemVo : orderItems) {

			if (null == orderItemVo.getActivity())
				continue;

			long activityId = Utils.zeroIfNull(orderItemVo.getActivity().getActivityId());

			if (activityId == 0)
				continue;

			Optional<ActivityCatalogVo> activityCatalogVo = SqActivityService
					.getActivityProductList(activityId, expectedOrder.getSellerId())
					.getList()
					.get(0)
					.getCatalogList()
					.stream()
					.filter(catalog -> catalog.getCatalogId().equalsIgnoreCase(orderItems.get(0).getCatalogId()))
					.findFirst();

			if (activityCatalogVo.get().getStockType() == 1) {

				waitInStock = true;
				break;
			}
		}

		if (isVerificationPreStock)
			waitInStock = false;

		Logger.verifyEquals(waitInStock, Utils.falseIfNull(actualOrder.getWaitInStock()),
				"验证数据库WaitInStock");
		Logger.verifyEquals(isVerificationPreStock ? true : null,
				actualOrder.getInStockTime() != null ? true : null,
				"验证数据库InStockTime");

		// 特殊情况，如果订单被风控且是线下支付的订单RiskOrder为true，一个主单所有子单都为true
		// 风控规则商品单价为20000，3个商品，总价60000
		if (actualOrder.getPayableAmount()
				.compareTo(new BigDecimal("60000.00")) == 0
				&& Utils.falseIfNull(actualOrder.getSupportOfflinePay()))
			Logger.verifyEquals(true, actualOrder.getPlaceRisk(),
					"验证数据库PlaceRisk");
		else
			Logger.verifyEquals(false, actualOrder.getPlaceRisk(),
					"验证数据库PlaceRisk");

		Logger.verifyEquals(expectedOrder.getAfterAcctivityFinishAccept(),
				actualOrder.getAfterActivityFinishAccept(),
				"验证数据库AfterActivityFinishAccept");
		
		if (isCDFMember(actualOrder.getSellerId())
				&& null != placeOrderReq.getIntegral()) {

			DataUtil.verifyDecimalEquals(
					new BigDecimal(actualOrder.getIntegral()),
					actualOrder.getIntegralDeductionAmount(),
					"验证数据库IntegralDeductionAmount");
			Logger.verifyEquals(actualOrder.getIntegral() >= 0, true,
					"验证数据库Integral");
		} else {

			DataUtil.verifyDecimalEquals(
					expectedOrder.getOrderIntegralDeduction(),
					actualOrder.getIntegralDeductionAmount(),
					"验证数据库IntegralDeductionAmount");
			Logger.verifyEquals(expectedOrder.getOrderIntegral(),
					actualOrder.getIntegral(), "验证数据库Integral");
		}
		
		Logger.verifyEquals(placeOrderReq.getIntegralServiceType(),
				actualOrder.getIntegralServiceType(),
				"验证数据库IntegralServiceType");
		
		DataUtil.verifyDecimalEquals(expectedOrder.getRegionDiscountValue(),
				actualOrder.getRegionDiscountAmount(),
				"验证数据库RegionDiscountAmount");
		DataUtil.verifyDecimalEquals(expectedOrder.getOrderVo().getRegionDiscountRatio(),
				actualOrder.getRegionDiscountRatio(), "验证数据库RegionDiscountRatio");
		
		DataUtil.verifyDecimalEquals(expectedOrder.getSellerCouponSource(),
				actualOrder.getSellerCouponSource(), "验证数据库SellerCouponSource");
		DataUtil.verifyDecimalEquals(expectedOrder.getSellerCouponType(),
				actualOrder.getSellerCouponType(), "验证数据库SellerCouponType");
		
		DataUtil.verifyDecimalEquals(expectedOrder.getOrderVo().getEarnestDeliveryPromiseDays(),
				actualOrder.getEarnestDeliveryPromiseDays(), "验证数据库EarnestDeliveryPromiseDays");
		
		Logger.verifyEquals(null, actualOrder.getIntegralExchangeRate(),
				"验证数据库IntegralExchangeRate");
	}

	/**
	 * 校验订单扩展表(order_ext)
	 * 
	 * @param expectOrder
	 * @param orderId
	 * @throws Exception
	 */
	private void verifyOrderExtDb(Order expectOrder, long orderId)
			throws Exception {

		// 等待下单回调处理完成
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		String phoneKey = "123456789";
		String addreeKey = "123456789";

		Logger.comment(String.format("校验订单扩展表(order_ext) orderId:%s", orderId));

		OrderExtPo actualOrderExt = orderWapper
				.selectOrderExtByOrderId(orderId);
		
		int n = 0;
		
		while (actualOrderExt == null) {
			
			n = n + 1;
			
			actualOrderExt = orderWapper
					.selectOrderExtByOrderId(orderId);
			
			if (n == 4) {
				
				Logger.comment("#############Thread.sleep(5000) 下单回调还没处理完");
				Logger.fail(new Exception("Thread.sleep(5000) 下单回调还没处理完"));
				return;
			}
			
			Thread.sleep(1000 * n);
		}

		if (placeOrderReq.getAddress() == null
				|| placeOrderReq.getAddress().equalsIgnoreCase(""))

			Logger.verifyEquals(placeOrderReq.getAddress(),
					actualOrderExt.getUserAddress(), "验证数据库userAddress");
		else {
			Logger.verifyEquals(CipherUtil.encryptAES(addreeKey,
					placeOrderReq.getAddress()), actualOrderExt
					.getUserAddress(), "验证数据库userAddress");
			Logger.verifyEquals(placeOrderReq.getAddress(),
					Utils.decryptAES(actualOrderExt.getUserAddress()),
					"验证数据库userAddress解密后的数据");
		}

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actualOrderExt.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actualOrderExt.getUpdateTime()) < 2,
				"验证数据库UpdateTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(orderId, actualOrderExt.getOrderId(),
				"验证数据库OrderId");

		Long sellerId = expectOrder.getSellerId();
		Logger.verifyEquals(sellerId, actualOrderExt.getSellerId(),
				"验证数据库SellerId");

		DGUserInfo dgUserInfo = new DGUserWapper().selectDGUserInfo(
				sellerId.intValue()).get(0);

		Logger.verifyEquals(dgUserInfo.getLoginId(),
				actualOrderExt.getSellerLoginId(), "验证数据库SellerLoginId");

		Long userId = placeOrderReq.getUserId();

		Logger.verifyEquals(userId, actualOrderExt.getUserId(), "验证数据库UserId");

		Logger.verifyEquals(null, actualOrderExt.getUserLoginId(),
				"验证数据库UserLoginId");

		Logger.verifyEquals(expectOrder.getDeviceId(),
				actualOrderExt.getDeviceId(), "验证数据库DeviceId");
		Logger.verifyEquals(expectOrder.getSourceIp(),
				actualOrderExt.getSourceIp(), "验证数据库SourceIp");
		Logger.verifyEquals(expectOrder.getEquipmentId(),
				actualOrderExt.getEquipmentId(), "验证数据库EquipmentId");
		Logger.verifyEquals(placeOrderReq.getPostCode(),
				actualOrderExt.getPostCode(), "验证数据库PostCode");

		Logger.verifyEquals(null, actualOrderExt.getSellerNote(),
				"验证数据库SellerNote");
		Logger.verifyEquals(expectOrder.getOrderVo().getLeaveWord(),
				actualOrderExt.getLeaveWord(), "验证数据库LeaveWord");
		Logger.verifyEquals(placeOrderReq.getOrderSource().name(),
				actualOrderExt.getSourcePlatform(), "验证数据库SourcePlatform");

		Logger.verifyEquals(placeOrderReq.getAppTerminalSource().name(),
				actualOrderExt.getSourceTerminal(), "验证数据库SourceTerminal");

		Logger.verifyEquals(placeOrderReq.getTerminalSource().name(),
				actualOrderExt.getOperatingSystem(), "验证数据库OperatingSystem");

		Logger.verifyEquals(null, actualOrderExt.getSellerNoteLevel(),
				"验证数据库SellerNoteLevel");

		// 如果下单有出行人信息，则将第一个出行人的电话、名称写入数据库
		if (placeOrderReq.getTravelerVos() != null
				&& placeOrderReq.getTravelerVos().size() != 0) {

			TravelerVo travelerVo = placeOrderReq.getTravelerVos().get(0);

			placeOrderReq.setRecvMobile(travelerVo.getTravelerPhone());
			placeOrderReq.setRecvName(travelerVo.getTravelerName());
		}

		if (placeOrderReq.getRecvMobile() == null
				|| placeOrderReq.getRecvMobile().equalsIgnoreCase(""))

			Logger.verifyEquals(placeOrderReq.getRecvMobile(),
					actualOrderExt.getUserPhone(), "验证数据库userPhone");
		else {
			Logger.verifyEquals(CipherUtil.encryptAES(phoneKey,
					Utils.trimAndLeft(placeOrderReq.getRecvMobile(), 20)),
					actualOrderExt.getUserPhone(), "验证数据库userPhone");

			Logger.verifyEquals(
					CipherUtil.decryptAES(phoneKey,
							actualOrderExt.getUserPhone()),
					Utils.trimAndLeft(placeOrderReq.getRecvMobile(), 20),
					"验证数据库userPhone解密后的数据");
		}

		Logger.verifyEquals(Utils.trimAndLeft(placeOrderReq.getRecvName(), 50),
				actualOrderExt.getReceiver(), "验证数据库Receiver");

//		Logger.verifyEquals(placeOrderReq.getPickupName(),
//				actualOrderExt.getPickupName(), "验证数据库PickupName");
//		Logger.verifyEquals(placeOrderReq.getPickupAddress(),
//				actualOrderExt.getPickupAddress(), "验证数据库PickupAddress");
//		Logger.verifyEquals(placeOrderReq.getPickupPhone(),
//				actualOrderExt.getPickupPhone(), "验证数据库PickupPhone");
//
//		if (placeOrderReq.getPickupUserPhone() == null)
//			Logger.verifyEquals(placeOrderReq.getPickupPhone(), null,
//					"验证数据库PickupPhone");
//		else {
//
//			Logger.verifyEquals(
//					CipherUtil.encryptAES(
//							phoneKey,
//							Utils.trimAndLeft(
//									placeOrderReq.getPickupUserPhone(), 20)),
//					actualOrderExt.getPickupUserPhone(), "验证数据库PickupUserPhone");
//			Logger.verifyEquals(
//					CipherUtil.decryptAES(phoneKey,
//							actualOrderExt.getPickupUserPhone()),
//					Utils.trimAndLeft(placeOrderReq.getPickupUserPhone(), 20),
//					"验证数据库PickupUserPhone解密后的数据");
//		}

		Logger.verifyEquals(placeOrderReq.getEntryIdType(),
				actualOrderExt.getEntryIdType(), "验证数据库EntryIdType");
		DataUtil.verifyDateEquals(placeOrderReq.getEntryTime(),
				actualOrderExt.getEntryTime(), "验证数据库EntryTime");
		Logger.verifyEquals(placeOrderReq.getEntryIdNo(),
				actualOrderExt.getEntryIdNo(), "验证数据库EntryIdNo");
		Logger.verifyEquals(placeOrderReq.getEntryPort(),
				actualOrderExt.getEntryPort(), "验证数据库EntryPort");
		Logger.verifyEquals(placeOrderReq.getTransportation(),
				actualOrderExt.getTransportation(), "验证数据库Transportation");
	}

	/**
	 * 校验订单商品表(order_detail)
	 * 
	 * @param expectedOrderDetails
	 * @param actualOrderDetails
	 * @throws Exception 
	 */
	private void verifyOrderDetailDb(List<OrderItem> expectedOrderDetails,
			List<OrderDetailPo> actualOrderDetails, Order expectedOrder,
			Long goodsOwnerId, boolean waitInStock) throws Exception {

		for (int i = 0; i < expectedOrderDetails.size(); i++) {

			OrderItem expectedOrderDetail = expectedOrderDetails.get(i);

			OrderDetailPo actualOrderDetail = actualOrderDetails.get(i);

			String goodsOwnerCatalogId = null;

			Logger.comment(String.format(
					"校验订单商品表(order_detail) orderId:%s,OrderDetailId:%s",
					actualOrderDetail.getOrderId(),
					actualOrderDetail.getOrderDetailId()));

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
					.getFreight(), actualOrderDetail.getFreight(),
					"验证数据库Freight");

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
					.getBookingPromotionAmount(), actualOrderDetail
					.getBookingPromotionAmount(), "验证数据库BookingPromotionAmount");

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
					.getEarnestAmount(), actualOrderDetail.getEarnestAmount(),
					"验证数据库EarnestAmount");

			Logger.verifyEquals(true,
					Utils.calcTimeSpanMin(actualOrderDetail.getAddTime()) < 2,
					"验证数据库AddTim跟系统当前时间差为2分钟内");

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
					.getProductPrice(), actualOrderDetail.getProductPrice(),
					"验证数据库ProductPrice");

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					actualOrderDetail.getThirdpartyDiscount(),
					"验证数据库ThirdpartyDiscount");

			DataUtil.verifyDecimalEquals(
					expectedOrderDetail.getSellerCouponValue(),
					actualOrderDetail.getSellerCouponAmount(),
					"验证数据库SellerCouponAmount");

			DataUtil.verifyDecimalEquals(
					expectedOrderDetail.getYmatouCouponValue(),
					actualOrderDetail.getYmtCouponAmount(),
					"验证数据库YmtCouponAmount");

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
					.getYmtPromotionAmount(), actualOrderDetail
					.getYmtPromotionAmount(), "验证数据库ymt_promotion_amount");

			DataUtil.verifyDecimalEquals(
					expectedOrderDetail.getSellerPromotionAmount(),
					actualOrderDetail.getPromotionAmount(),
					"验证数据库PromotionAmount");

			Logger.verifyEquals(
					true,
					Utils.calcTimeSpanMin(actualOrderDetail.getUpdateTime()) < 2,
					"验证数据库UpdateTime跟系统当前时间差为2分钟内");

			Logger.verifyEquals(expectedOrderDetail.getItemVo().getProductId(),
					actualOrderDetail.getProductId(), "验证数据库ProductId");

			Logger.verifyEquals(expectedOrderDetail.getItemVo().getCatalogId(),
					actualOrderDetail.getCatalogId(), "验证数据库CatalogId");

			Logger.verifyEquals(expectedOrderDetail.getItemVo()
					.getStockStatus() == null ? 0 : expectedOrderDetail
					.getItemVo().getStockStatus().getCode(), actualOrderDetail
					.getCatalogType(), "验证数据库CatalogType");

			Logger.verifyEquals(
					expectedOrderDetail.getItemVo().getProductNum(),
					actualOrderDetail.getProductCount(), "验证数据库ProductCount");

			if (expectedOrderDetail.getItemVo().getBondedArea() != null) {
				Logger.verifyEquals(expectedOrderDetail.getItemVo()
						.getBondedArea().getCode(),
						actualOrderDetail.getBondedArea(), "验证数据库BondedArea");
			}

			Logger.verifyEquals(
					expectedOrderDetail.getItemVo().getProductVer(),
					actualOrderDetail.getProductSnap(), "验证数据库ProductSnap");

			Logger.verifyEquals(
					expectedOrderDetail.getItemVo().getPriceType() == null ? 0
							: expectedOrderDetail.getItemVo().getPriceType()
									.getCode(), actualOrderDetail
							.getPriceType(), "验证数据库PriceType");

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
					.getOriginalPrice(), actualOrderDetail.getOriginalPrice(),
					"验证数据库OriginalPrice");

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getDiscount(),
					actualOrderDetail.getDiscount(), "验证数据库Discount");

			long activityId = 0, activityTemplateId = 0, productInActivityId = 0;

			if (expectedOrderDetail.getItemVo().getActivity() != null) {

				activityId = expectedOrderDetail.getItemVo().getActivity()
						.getActivityId();

				activityTemplateId = expectedOrderDetail.getItemVo()
						.getActivity().getActivityTemplateId();

				productInActivityId = expectedOrderDetail.getItemVo()
						.getActivity().getProductInActivityId();
			}

			Logger.verifyEquals(activityId,
					Long.valueOf(actualOrderDetail.getActivityId()),
					"验证数据库ActivityId");

			Logger.verifyEquals(
					expectedOrderDetail.getItemVo().getTariffType(),
					actualOrderDetail.getTariffType(), "验证数据库TariffType");

			if (expectedOrderDetail.getItemVo().getProductRefundChannel() != null) {

				Logger.verifyEquals(expectedOrderDetail.getItemVo()
						.getProductRefundChannel().getCode(),
						actualOrderDetail.getRefundChannel(),
						"验证数据库RefundChannel");
			}

			if (expectedOrderDetail.getItemVo().getSalesType() != null) {

				Logger.verifyEquals(expectedOrderDetail.getItemVo()
						.getSalesType().getCode(),
						actualOrderDetail.getSalesType(), "验证数据库SalesType");
			}

			Logger.verifyEquals(
					expectedOrderDetail.getItemVo().isFreightFree(),
					actualOrderDetail.getFreeFreight(), "验证数据库FreeFreight");
			Logger.verifyEquals(expectedOrderDetail.getItemVo().isPspProduct(),
					actualOrderDetail.getPspProduct(), "验证数据库PspProduct");
			Logger.verifyEquals(expectedOrderDetail.getItemVo().isSubProduct(),
					actualOrderDetail.getSubProduct(), "验证数据库SubProduct");

			Logger.verifyEquals(expectedOrderDetail.getItemVo()
					.getFirstCategoryId(), Long.valueOf(actualOrderDetail
					.getFirstCategoryId()), "验证数据库FirstCategoryId");
			Logger.verifyEquals(expectedOrderDetail.getItemVo()
					.getSecondCategoryId(), Long.valueOf(actualOrderDetail
					.getSecondCategoryId()), "验证数据库SecondCategoryId");

			Logger.verifyEquals(expectedOrderDetail.getItemVo()
					.getThirdCategoryId(), Long.valueOf(actualOrderDetail
					.getThirdCategoryId()), "验证数据库ThirdCategoryId");

			Logger.verifyEquals(activityTemplateId,
					Long.valueOf(actualOrderDetail.getActivityTempId()),
					"验证数据库ActivityTempId");

			Logger.verifyEquals(productInActivityId,
					Long.valueOf(actualOrderDetail.getProductInActivityId()),
					"验证数据库ProductInActivityId");

			Logger.verifyEquals(expectedOrderDetail.getItemVo()
					.isSupportsRtnWithoutReason(), actualOrderDetail
					.getSupportNoReasonRefund(), "验证数据库SupportNoReasonRefund");
			
			if (expectedOrderDetail.getSellerPromotion() != null) {

				OrderDetailPromotionPo actualOrderDetailPromotion = orderShardingWapper
						.selectOrderDetailPromotionByOrderDetailId(actualOrderDetail
								.getOrderDetailId());

				// 校验订单营销表（order_detail_promotion）
				verifyService.verifyOrderDetailPromotionDb(expectedOrderDetail,
						actualOrderDetailPromotion,
						actualOrderDetail.getOrderId());
			}
			
			boolean fullReductionFreeFreight = Utils
					.falseIfNull(actualOrderDetail
							.getFullReductionFreeFreight());

			int scale = 0;

			if (null == placeOrderReq.getCurrency())
				scale = 2;
			else if (null != placeOrderReq.getCurrency()
					&& placeOrderReq.getCurrency().equalsIgnoreCase("JPY"))
				scale = 0;

			// 直销商没有代理价，有代理价的情况才会查询代理链
			if (null != actualOrderDetail.getProxyPrice()) {

				long sellerId = placeOrderReq.getOrderGroups().get(0)
						.getSellerId();
				String catalogId = actualOrderDetail.getCatalogId();

				boolean isInherited = GodmchManageCallService
						.isInheritedAgent(sellerId);

				// 校验神器链条表
				List<ShenqiProxyChainPo> expectedShenqiProxyChainPoList = isInherited ? SqTradingProductService
						.getInheritedProxyChainInfo(catalogId, sellerId)
						: SqTradingProductService
								.getProxyChainInfoList(catalogId, sellerId);

				expectedShenqiProxyChainPoList
						.get(expectedShenqiProxyChainPoList.size() - 1)
						.setPictureUrl(
								expectedOrderDetail.getItemVo().getPictureUrl());
				expectedShenqiProxyChainPoList.get(
						expectedShenqiProxyChainPoList.size() - 1).setTitle(
						expectedOrderDetail.getItemVo().getProductName());

				Logger.verifyEquals(
						expectedShenqiProxyChainPoList.get(
								expectedShenqiProxyChainPoList.size() - 1)
								.getFromParentPrice(), actualOrderDetail
								.getProxyPrice(), "验证数据库ProxyPrice");

				verifyService.verifyShenqiProxyChainDb(expectedShenqiProxyChainPoList,
						actualOrderDetail.getOrderId(),
						actualOrderDetail.getCatalogId());

				goodsOwnerCatalogId = expectedShenqiProxyChainPoList.get(0)
						.getProxyCatalogId();

				DataUtil.verifyDecimalEquals(null,
						actualOrderDetail.getServiceRate(), "验证数据库ServiceRate");
				DataUtil.verifyDecimalEquals(null,
						actualOrderDetail.getServiceAmount(),
						"验证数据库serviceAmount");
				
				DataUtil.verifyDecimalEquals(expectedShenqiProxyChainPoList
						.get(expectedShenqiProxyChainPoList.size() - 1)
						.getCostPrice(), actualOrderDetail.getPrimeCostPrice(),
						"验证数据库PrimeCostPrice");
			} else {

				BigDecimal serviceRate = expectedOrderDetail.getServiceRate();
				BigDecimal serviceAmount = SqTradingCallService
						.getServiceAmount(actualOrderDetail);

				// 直销订单验证服务费
				DataUtil.verifyDecimalEquals(Utils.zeroIfNull(serviceRate),
						actualOrderDetail.getServiceRate(), "验证数据库ServiceRate");
				DataUtil.verifyDecimalEquals(
						serviceAmount.setScale(scale, BigDecimal.ROUND_HALF_UP),
						actualOrderDetail.getServiceAmount(),
						"验证数据库serviceAmount");
				
				DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
						.getPrimeCostPrice(),
						actualOrderDetail.getPrimeCostPrice(),
						"验证数据库PrimeCostPrice");
				
				// 如果是一品多码商户且该商品不是组合商品，校验一品多码表
				if (goodsOwnerId == multiCDFCodeGoodsOwnerId
						&& !expectedOrderDetail.getItemVo().isSubProduct())
					verifyService.verifyOrderDetailSubCodeDb(actualOrderDetail.getOrderId(),
							expectedOrderDetail.getItemVo().getCatalogId(),
							waitInStock ? 0 : expectedOrderDetail.getItemVo().getProductNum());
				
				goodsOwnerCatalogId = actualOrderDetail.getCatalogId();
			}

			DataUtil.verifyDecimalEquals(Utils.zeroIfNull(expectedOrderDetail
					.getItemVo().getProdTaxRate()), actualOrderDetail
					.getTaxRate(), "验证数据库TaxRate");

			BigDecimal taxFee = Utils
					.zeroIfNull(
							fullReductionFreeFreight ? BigDecimal.ZERO
									: actualOrderDetail.getFreight())
					.divide(new BigDecimal(actualOrderDetail.getProductCount()),
							32, RoundingMode.DOWN)
					.add(actualOrderDetail.getProductPrice())
					.add(Utils.zeroIfNull(actualOrderDetail.getDiscount())
							.divide(new BigDecimal(actualOrderDetail
									.getProductCount()), 32, RoundingMode.DOWN))
					.subtract(
							Utils.zeroIfNull(actualOrderDetail
									.getYmtCouponAmount()))
					.subtract(
							Utils.zeroIfNull(actualOrderDetail
									.getYmtPromotionAmount()))
					.subtract(
							Utils.zeroIfNull(
									actualOrderDetail.getSellerCouponAmount())
									.divide(new BigDecimal(actualOrderDetail
											.getProductCount()), 32,
											RoundingMode.DOWN))
					.subtract(
							Utils.zeroIfNull(
									actualOrderDetail.getPromotionAmount())
									.divide(new BigDecimal(actualOrderDetail
											.getProductCount()), 32,
											RoundingMode.DOWN))
					.subtract(
							Utils.zeroIfNull(
									actualOrderDetail.getRegionDiscountAmount())
									.divide(new BigDecimal(actualOrderDetail
											.getProductCount()), 32,
											RoundingMode.DOWN))
					.multiply(actualOrderDetail.getTaxRate())
					.setScale(scale, RoundingMode.HALF_DOWN);

			if (SqTradingCallService.isFreePerimeters(placeOrderReq
					.getAddress()))
				DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
						actualOrderDetail.getTaxFee(), "验证数据库TaxFee");
			else
				DataUtil.verifyDecimalEquals(taxFee,
						actualOrderDetail.getTaxFee(), "验证数据库TaxFee");

			Logger.verifyEquals(expectedOrderDetail.getItemVo()
					.isBuyDailyLimit(), actualOrderDetail.isDailyLimit(),
					"验证数据库DailyLimit");

			DataUtil.verifyDecimalEquals(expectedOrderDetail.getItemVo()
					.getVirtualProductNum(), Utils.zeroIfNull(actualOrderDetail
					.getvStockCount()), "验证数据库vStockCount");

			if (null == expectedOrder.getOrderVo().getCrossBorderType()) {
				Logger.verifyEquals(expectedOrderDetail.getItemVo()
						.getDomesticProduct(), actualOrderDetail
						.getDomesticProduct(), "验证数据库DomesticProduct");

			} else {

				if (Utils.zeroIfNull(expectedOrder.getOrderVo()
						.getCrossBorderType()) != 2)
					Logger.verifyEquals(false,
							actualOrderDetail.getDomesticProduct(),
							"验证数据库DomesticProduct");
				else
					Logger.verifyEquals(true,
							actualOrderDetail.getDomesticProduct(),
							"验证数据库DomesticProduct");
			}

			Logger.verifyEquals(Utils.zeroIfNull(actualOrderDetail
					.getvStockCount()) > 0 ? true : false, Utils
					.falseIfNull(actualOrderDetail.getWaitInStock()),
					"验证数据库WaitInStock");
			Logger.verifyEquals(goodsOwnerCatalogId,
					actualOrderDetail.getGoodsOwnerCatalogId(),
					"验证数据库GoodsOwnerCatalogId");
			Logger.verifyEquals(null, actualOrderDetail.getInStockTime(),
					"验证数据库InStockTime");
			
			if (isCDFMember(goodsOwnerId)
					&& null != placeOrderReq.getIntegral()) {

				DataUtil.verifyDecimalEquals(
						new BigDecimal(actualOrderDetail.getIntegral()),
						actualOrderDetail.getIntegralDeductionAmount(),
						"验证数据库IntegralDeductionAmount");
				Logger.verifyEquals(actualOrderDetail.getIntegral() >= 0, true,
						"验证数据库Integral");
			} else {

				DataUtil.verifyDecimalEquals(
						expectedOrderDetail.getIntegralDeduction(),
						actualOrderDetail.getIntegralDeductionAmount(),
						"验证数据库IntegralDeductionAmount");
				Logger.verifyEquals(expectedOrderDetail.getIntegral(),
						actualOrderDetail.getIntegral(), "验证数据库Integral");
			}
			
			Logger.verifyEquals(Utils.falseIfNull(expectedOrderDetail
					.getItemVo().getExchangeBuy()), actualOrderDetail
					.getExchangeBuy(), "验证数据库ExchangeBuy");
			Logger.verifyEquals(expectedOrderDetail
					.getItemVo().getExchangeBuyActivityId(), actualOrderDetail
					.getExchangeBuyActivityId(), "验证数据库ExchangeBuyActivityId");

			// 校验订单商品扩展表(order_detail_ext)
			verifyOrderDetailExtDb(expectedOrderDetail, actualOrderDetail);

			// 订单商品是 套装商品
			if (expectedOrderDetail.getItemVo().isSubProduct()) {

				// 校验订单组合子商品表（order_detail_sub）
				verifyOrderDetailSubDb(actualOrderDetail, goodsOwnerId);
			}
			
			BigDecimal productEarnestAmount = expectedOrderDetail.getItemVo()
					.getEarnestAmount();
			
			if (null != productEarnestAmount
					&& productEarnestAmount.compareTo(BigDecimal.ZERO) == 1
					&& !Utils.falseIfNull(expectedOrder.getOrderVo()
							.getBookingConfirmOrder()))
				DataUtil.verifyDecimalEquals(productEarnestAmount
						.multiply(new BigDecimal(actualOrderDetail
								.getProductCount())), actualOrderDetail
						.getPayableAmount(), "验证数据库PayableAmount");
			else {
				BigDecimal payableAmount = Utils
						.zeroIfNull(
								fullReductionFreeFreight ? BigDecimal.ZERO
										: actualOrderDetail.getFreight())
						.add(actualOrderDetail.getProductPrice().multiply(
								new BigDecimal(actualOrderDetail
										.getProductCount())))
						.add(Utils.zeroIfNull(actualOrderDetail.getDiscount()))
						.add(actualOrderDetail.getTaxFee().multiply(
								new BigDecimal(actualOrderDetail
										.getProductCount())))
						.add(actualOrderDetail.getServiceAmount())
						.subtract(
								actualOrderDetail.getIntegralDeductionAmount())
						.subtract(
								Utils.zeroIfNull(actualOrderDetail
										.getYmtCouponAmount()))
						.subtract(
								Utils.zeroIfNull(actualOrderDetail
										.getYmtPromotionAmount()))
						.subtract(
								Utils.zeroIfNull(actualOrderDetail
										.getSellerCouponAmount()))
						.subtract(
								Utils.zeroIfNull(actualOrderDetail
										.getPromotionAmount()))
						.subtract(
								Utils.zeroIfNull(actualOrderDetail
										.getRegionDiscountAmount()));

				DataUtil.verifyDecimalEquals(payableAmount,
						actualOrderDetail.getPayableAmount(),
						"验证数据库PayableAmount");
			}

			DataUtil.verifyDecimalEquals(
					expectedOrderDetail.getRegionDiscountValue(),
					actualOrderDetail.getRegionDiscountAmount(),
					"验证数据库RegionDiscountAmount");
		}
	}

	/**
	 * 校验订单商品扩展表(order_detail_ext)
	 * 
	 * @param expectedOrderDetail
	 * @param actualOrderDetail
	 */
	private void verifyOrderDetailExtDb(OrderItem expectedOrderDetail,
			OrderDetailPo actualOrderDetail) {

		Long orderDetailId = actualOrderDetail.getOrderDetailId();

		Logger.comment(String.format(
				"校验订单商品表扩展表(order_detail_ext) orderId:%s,OrderDetailId:%s",
				actualOrderDetail.getOrderId(), orderDetailId));

		OrderDetailExtPo actualOrderDetailExt = orderWapper
				.selectOrderDetailExtByOrderId(actualOrderDetail
						.getOrderDetailId());

		Logger.verifyEquals(orderDetailId,
				actualOrderDetailExt.getOrderDetailId(), "验证数据库OrderDetailId");
		Logger.verifyEquals(actualOrderDetail.getCatalogId(),
				actualOrderDetailExt.getCatalogId(), "验证数据库CatalogId");

		Logger.verifyEquals(
				true,
				Utils.calcTimeSpanMin(actualOrderDetailExt.getUpdateTime()) < 2,
				"验证数据库UpdateTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actualOrderDetailExt.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(actualOrderDetail.getOrderId(),
				actualOrderDetailExt.getOrderId(), "验证数据库OrderId");
		Logger.verifyEquals(expectedOrderDetail.getItemVo().getProperty(),
				actualOrderDetailExt.getPropertyInfo(), "验证数据库PropertyInfo");
		Logger.verifyEquals(expectedOrderDetail.getItemVo().getBrandId(),
				actualOrderDetailExt.getBrandId(), "验证数据库BrandId");
		Logger.verifyEquals(expectedOrderDetail.getItemVo().getPictureUrl(),
				actualOrderDetailExt.getPictureUrl(), "验证数据库PictureUrl");
		Logger.verifyEquals(expectedOrderDetail.getItemVo().getSku(),
				actualOrderDetailExt.getSku(), "验证数据库Sku");
		Logger.verifyEquals(expectedOrderDetail.getItemVo().getProductName(),
				actualOrderDetailExt.getTitle(), "验证数据库Title");
		Logger.verifyEquals(expectedOrderDetail.getItemVo()
				.getProductRecordNo(), actualOrderDetailExt.getRecordNo(),
				"验证数据库RecordNo");
	}

	/**
	 * 校验订单组合子商品表（order_detail_sub）
	 *
	 * @param actualOrderDetail
	 * @throws Exception
	 */
	private void verifyOrderDetailSubDb(OrderDetailPo actualOrderDetail,
			Long goodsOwnerId) throws Exception {

		long orderDetailId = actualOrderDetail.getOrderDetailId();
		long orderId = actualOrderDetail.getOrderId();

		orderShardingWapper.clearCache();

		List<OrderDetailSubPo> actualSubPoList = orderShardingWapper
				.selectOrderDetailSubByDetailId(orderDetailId)
				.stream()
				.sorted(Comparator.comparing(OrderDetailSubPo::getSubCatalogId))
				.collect(Collectors.toList());

		String catalogId = actualOrderDetail.getCatalogId();

		PackageInfoByCatalogIdListResponse response = SqTradingProductService
				.getPackageInfoByCatalogIdList(goodsOwnerId,
						Arrays.asList(catalogId));

		List<SubCatalog> subCataLogs = response.getProductPackageList().get(0)
				.getSubCatalogList().stream()
				.sorted(Comparator.comparing(SubCatalog::getOriginCatalogId))
				.collect(Collectors.toList());

		if (CollectionUtils.isEmpty(actualSubPoList)) {

			String msg = String
					.format("校验订单组合子商品表（order_detail_sub） orderId:%s,catalogId:%s 套装子商品为null",
							actualOrderDetail.getOrderId(), catalogId);
			Logger.comment(msg);

			Logger.fail(new Exception(msg));

			return;
		}

		Logger.verifyEquals(subCataLogs.size(), actualSubPoList.size(),
				"验证子商品个数");

		Logger.comment(String.format(
				"校验订单组合子商品表（order_detail_sub） orderId:%s,catalogId:%s",
				actualOrderDetail.getOrderId(), catalogId));

		BigDecimal fProductPrice = actualOrderDetail.getProductPrice();

		int iAmount = actualOrderDetail.getProductCount();

		// 运费
		BigDecimal fFreight = actualOrderDetail.getFullReductionFreeFreight() ? BigDecimal.ZERO
				: actualOrderDetail.getFreight();

		// 买手优惠券
		BigDecimal fSellerCouponAmount = actualOrderDetail
				.getSellerCouponAmount();

		// 平台优惠券
		BigDecimal fYmtCouponAmount = actualOrderDetail.getYmtCouponAmount();

		// 买手优惠金额
		BigDecimal fSellerPromotionAmount = actualOrderDetail
				.getPromotionAmount();

		// 平台优惠金额
		BigDecimal fymtPromotionAmount = actualOrderDetail
				.getYmtPromotionAmount();

		// 商品税费
		BigDecimal fTaxFee = actualOrderDetail.getTaxFee();

		// 折扣金额
		BigDecimal fDiscount = actualOrderDetail.getDiscount();

		// 商品积分
		Long fIntegral = actualOrderDetail.getIntegral();

		// 积分抵扣金额
		BigDecimal fIntegralDeductionAmount = actualOrderDetail
				.getIntegralDeductionAmount();

		// 区域折扣金额
		BigDecimal fRegionDiscountAmount = actualOrderDetail
				.getRegionDiscountAmount();
		
		// 预售立减金额
		BigDecimal fBookingPromotionAmount = actualOrderDetail
				.getBookingPromotionAmount().multiply(
						new BigDecimal(actualOrderDetail.getProductCount()));

		// 分摊权重
		BigDecimal[] weight = new BigDecimal[subCataLogs.size()];

		for (int j = 0; j < subCataLogs.size(); j++) {

			SubCatalog subCatalog = subCataLogs.get(j);

			weight[j] = subCatalog.getPrice().multiply(
					new BigDecimal(subCatalog.getNum()));
		}

		BigDecimal price[] = Utils.apportionByWeights(
				fProductPrice.multiply(new BigDecimal(iAmount)), weight);

		BigDecimal freight[] = Utils.apportionByWeights(fFreight, weight);

		BigDecimal sellerCoupon[] = Utils.apportionByWeights(
				fSellerCouponAmount, weight);

		BigDecimal ymtCoupon[] = Utils.apportionByWeights(fYmtCouponAmount,
				weight);

		BigDecimal sellerPromotionAmount[] = Utils.apportionByWeights(
				fSellerPromotionAmount, weight);

		BigDecimal ymtPromotionAmount[] = Utils.apportionByWeights(
				fymtPromotionAmount, weight);

		BigDecimal discount[] = Utils.apportionByWeights(fDiscount, weight);

		BigDecimal taxFee[] = Utils.apportionByWeights(
				fTaxFee.multiply(new BigDecimal(iAmount)), weight);

		BigDecimal integral[] = Utils.apportionByWeightsWithCurrency(
				new BigDecimal(fIntegral), weight, "JPY");

		BigDecimal integralDeductionAmount[] = Utils.apportionByWeights(
				fIntegralDeductionAmount, weight);

		BigDecimal regionDiscountAmount[] = Utils.apportionByWeights(
				fRegionDiscountAmount, weight);
		
		BigDecimal bookingPromotionAmount[] = Utils.apportionByWeights(
				fBookingPromotionAmount, weight);

		int k = 0;

		for (OrderDetailSubPo actualOrderDetailSub : actualSubPoList) {

			Logger.comment(String.format("套装子商品序号 %s",
					actualOrderDetailSub.getId()));

			Logger.verifyEquals(orderId, actualOrderDetailSub.getOrderId(),
					"验证数据库OrderId");

			Logger.verifyEquals(orderDetailId,
					actualOrderDetailSub.getOrderDetailId(),
					"验证数据库OrderDetailId");

			DataUtil.verifyDecimalEquals(freight[k],
					actualOrderDetailSub.getFreight(), "验证数据库Freight");

			Logger.verifyEquals(
					true,
					Utils.calcTimeSpanMin(actualOrderDetailSub.getAddTime()) < 2,
					"验证数据库AddTime跟系统当前时间差为2分钟内");

			Logger.verifyEquals(
					true,
					Utils.calcTimeSpanMin(actualOrderDetailSub.getUpdateTime()) < 2,
					"验证数据库UpdateTime跟系统当前时间差为2分钟内");

			DataUtil.verifyDecimalEquals(sellerPromotionAmount[k],
					actualOrderDetailSub.getPromotionAmount(),
					"验证数据库PromotionAmount");

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					actualOrderDetailSub.getThirdpartyDiscount(),
					"验证数据库ThirdpartyDiscount");

			Logger.verifyEquals(catalogId, actualOrderDetailSub.getCatalogId(),
					"验证数据库CatalogId");

			DataUtil.verifyDecimalEquals(ymtCoupon[k],
					actualOrderDetailSub.getYmtCouponAmount(),
					"验证数据库YmtCouponAmount");

			DataUtil.verifyDecimalEquals(sellerCoupon[k],
					actualOrderDetailSub.getSellerCouponAmount(),
					"验证数据库SellerCouponAmount");

			DataUtil.verifyDecimalEquals(ymtPromotionAmount[k],
					actualOrderDetailSub.getYmtPromotionAmount(),
					"验证数据库ymtPromotionAmount");

			DataUtil.verifyDecimalEquals(discount[k],
					actualOrderDetailSub.getDiscount(), "验证数据库Discount");

			DataUtil.verifyDecimalEquals(price[k],
					actualOrderDetailSub.getProductPrice(), "验证数据库ProductPrice");

			DataUtil.verifyDecimalEquals(taxFee[k],
					actualOrderDetailSub.getTotalTaxFee(), "验证数据库TotalTaxFee");

			Logger.verifyEquals(subCataLogs.get(k).getMainPic(),
					actualOrderDetailSub.getPictureUrl(), "验证数据库PictureUrl");

			Logger.verifyEquals(subCataLogs.get(k).getPropertyValue(),
					actualOrderDetailSub.getPropertyInfo(), "验证数据库PropertyInfo");

			if (isCDFMember(goodsOwnerId)) {

				Logger.verifyEquals(true,
						actualOrderDetailSub.getIntegral() >= 0,
						"验证数据库Integral");

				DataUtil.verifyDecimalEquals(new BigDecimal(
						actualOrderDetailSub.getIntegral()),
						actualOrderDetailSub.getIntegralDeductionAmount(),
						"验证数据库IntegralDeductionAmount");
			} else {

				DataUtil.verifyDecimalEquals(integral[k],
						actualOrderDetailSub.getIntegral(), "验证数据库Integral");

				DataUtil.verifyDecimalEquals(integralDeductionAmount[k],
						actualOrderDetailSub.getIntegralDeductionAmount(),
						"验证数据库IntegralDeductionAmount");
			}

			DataUtil.verifyDecimalEquals(regionDiscountAmount[k],
					actualOrderDetailSub.getRegionDiscountAmount(),
					"验证数据库RegionDiscountAmount");
			
			DataUtil.verifyDecimalEquals(bookingPromotionAmount[k],
					actualOrderDetailSub.getBookingPromotionAmount(),
					"验证数据库BookingPromotionAmount");

			k++;
		}

		if (goodsOwnerId == multiCDFCodeGoodsOwnerId) {

			int totalCount = actualSubPoList.stream()
					.map(subPo -> subPo.getProductCount()).reduce(Integer::sum)
					.orElse(0);

			verifyService.verifyOrderDetailSubCodeDb(actualOrderDetail.getOrderId(),
					actualOrderDetail.getCatalogId(), totalCount
							* actualOrderDetail.getProductCount());
		}
	}

	// 验证二次确认的订单变化部分
	public void verifyBookingOrder(List<Long> bookingOrderIds) {

		for (int i = 0; i < bookingOrderIds.size(); i++) {

			OrderPo actualOrder = orderShardingWapper
					.selectOrderbyOrderId(bookingOrderIds.get(i));

			Logger.comment(String.format("校验预定订单：%s", bookingOrderIds.get(i)));
			Logger.verifyEquals(false, actualOrder.getCanConfirm(),
					"验证数据库CanConfirm");
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_001() {
		Logger.start(true, "创建预定订单,下单成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.getOrders()
					.get(0)
					.getOrderItems()
					.get(0)
					.setEarnestAmount(
							TestDataManager.randomPrice(BigDecimal.ZERO,
									BigDecimal.TEN));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setDomesticProduct(true);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setEarnestDeliveryPromiseDays(1);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_002() {
		Logger.start(true, "一次下单,预定订单，普通订单混合下单，下单失败");
		try {
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							false);

			// 买手1 订单组
			OrderGroupVo groupVo1 = placeOrderReq.getOrderGroups().get(0);

			OrderVo orderVo1 = SqTradingCallService.createOrderVo(Arrays.asList(productBean));

			orderVo1.setOrderItems(Arrays.asList(SqTradingCallService
					.createOrderItemVo(TestDataManager.getRandomUUID()
							.toString(), TestDataManager.getRandomUUID()
							.toString()), SqTradingCallService.createOrderItemVo(
					TestDataManager.getRandomUUID().toString(), TestDataManager
							.getRandomUUID().toString()), SqTradingCallService
					.createOrderItemVo(TestDataManager.getRandomUUID()
							.toString(), TestDataManager.getRandomUUID()
							.toString())));

			groupVo1.getOrders().add(orderVo1);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单不能混合下单！", placeorderCall.getMsg(), "校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_003() {
		Logger.start(true, "创建预定订单,使用买手优惠券，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							true);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单不可以使用买手优惠券！", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_004() {
		Logger.start(true, "创建预定订单,参加商家优惠，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProductNum(1);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);

			OrderItemVo orderItemVo2 = SqTradingCallService
					.createOrderItemVo(productBean.getProductId(), productBean
							.getCatalogList().get(1));

			orderItemVo2.setProductPrice(new BigDecimal("2000.00"));
			orderItemVo2.setProductNum(2);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().add(orderItemVo2);

			// 定义买手下的优惠商品信息list
			List<SellerPromotionVo> sellerPromotionList = new ArrayList<SellerPromotionVo>();

			SellerPromotionVo sellerPromotion1 = new SellerPromotionVo();

			sellerPromotion1.setAmountCondition(new BigDecimal(100));
			sellerPromotion1.setId(123456789);
			sellerPromotion1.setName("自动化商家优惠活动");

			sellerPromotion1.setPromotionValue(new BigDecimal(12));
			sellerPromotion1.setQtyCondition(4);

			sellerPromotion1.setReducedAmount(new BigDecimal("15.00"));
			sellerPromotion1.setType(PromotionTypeEnum.ReduceIfAmountEnough);

			sellerPromotion1.setApportions(Arrays.asList(
					new CatalogApportionVo(productBean.getCatalogList().get(0),
							orderItemVo1.getProductNum()),
					new CatalogApportionVo(orderItemVo2.getCatalogId(),
							orderItemVo2.getProductNum())));

			sellerPromotionList.add(sellerPromotion1);

			placeOrderReq.getOrderGroups().get(0)
					.setSellerPromotionApportions(sellerPromotionList);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单不可以使用买手促销优惠！", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_005() {
		Logger.start(true, "创建预定订单,使用电子券，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProductNum(1);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);
			
			// 领取cdf优惠券
			CDFMemberService.getCdfCoupon(CouponTypeEnum.CASH_COUPON.getCode(),
					1, 26080783L);

			CouponVo couponVo = SqTradingCallService.createCouponVo(
					CDFMemberService.getLatestUnuseCdfCoupon(26080783L,
							cdfMembergoodsOwnerId), BigDecimal.ONE);

			couponVo.setCouponSource(1);
			couponVo.setCouponType(CouponTypeEnum.CASH_COUPON.getCode());
			
			placeOrderReq.getOrderGroups().get(0).setSellerCoupon(couponVo);

			placeOrderReq.setIntegralServiceType(2);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单不可以使用买手优惠券！", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_006() {
		Logger.start(true, "创建预定订单,使用积分，下单失败");
		try {
			
			CDFMemberService.getCDFMemberUserPoints(cdfMembergoodsOwnerId,
					26080783L);
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProductNum(1);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);
			orderItemVo1.setSku("C052900");
			orderItemVo1.setProductRecordNo("C052900");
			
			placeOrderReq.setIntegral(1L);
			placeOrderReq.setIntegralServiceType(2);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单定金不能使用积分支付！", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_007() {
		Logger.start(true, "创建预定订单,设置满减包邮，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProductNum(1);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);
			orderItemVo1.setFullReductionFreeFreight(true);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单不可以包含满减包邮活动！", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_008() {
		Logger.start(true, "创建预定订单,设置区域折扣，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProductNum(1);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setRegionDiscountRatio(BigDecimal.ONE);
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单不可以使用区域折扣！", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_009() {
		Logger.start(true, "创建预定订单,设置服务费，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) cdfMembergoodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProductNum(1);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);
			
			placeOrderReq.getOrderGroups().get(0)
					.setServiceRate(BigDecimal.ONE);
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单定金不包含服务费！", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_010() {
		Logger.start(true, "创建预定订单,代理订单，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 1, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProductNum(1);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals("预售订单必须是直销订单(分销小店上级为渠道商)", placeorderCall.getMsg(),
					"校验msg");

			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	// 预订订单使用预售库存，不适用虚拟库存
	public void Tc_SqBookingPlaceOrder_011() {
		Logger.start(true, "创建预定订单,占用虚拟库存，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			
			// 实际库存10 + 虚拟库存2
			orderItemVo1.setProductNum(12);
			orderItemVo1.setVirtualProductNum(2);
			orderItemVo1.setPrimeCostPrice(BigDecimal.TEN);
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_012() {
		Logger.start(true, "创建预定订单,每日限购，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);
			
			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setBuyDailyLimit(true);
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_013() {
		Logger.start(true, "创建预定订单,使用订单别名，境内购买，使用分仓id，使用入境人信息，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);
			
			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setDomesticProduct(true);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setOrderAlias("order1");
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setWarehouseId(2134567);
			
			placeOrderReq.setEntryIdType(1);
			placeOrderReq.setEntryIdNo(TestDataManager.randomStr(8));
			placeOrderReq.setEntryTime(YMTDateUtil.getBeforeOrNextDate(
					YMTDateUtil.getDate(), 1));
			placeOrderReq.setEntryPort("entryPPPPP");
			placeOrderReq.setTransportation("autotest_flight");
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_015() {
		Logger.start(true, "创建预定订单,使用自提信息，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);
			
			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			
			placeOrderReq.setPickupInStores(true);
			PickInStoreVo pickInStoreVo = new PickInStoreVo();

			pickInStoreVo.setPickupStoreId((long) TestDataManager
					.getRandomIntNum(6));
			pickInStoreVo.setPickupType(0);
			pickInStoreVo.setPickupUserName(TestDataManager.getChineseName());
			pickInStoreVo.setPickupUserPhone(TestDataManager.getPhoneNum());
			pickInStoreVo.setUserReserveTimeSpanStart(YMTDateUtil
					.getBeforeOrNextDate(0));
			pickInStoreVo.setUserReserveTimeSpanEnd(YMTDateUtil
					.getBeforeOrNextDate(10));

			placeOrderReq.setPickInStoreVo(pickInStoreVo);
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_016() {
		Logger.start(true, "创建预定订单,包含税费，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);
			
			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setProdTaxRate(new BigDecimal("0.17"));
			
			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_017() {
		Logger.start(true, "创建预定订单,一品多码组合商品，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createComposeProductProxychain(
							(int) multiCDFCodeGoodsOwnerId, false, true);

			placeOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setSubProduct(true);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_018() {
		Logger.start(true, "分销小店创建预定订单,下单成功");
		try {

			Integer mchId = DGSQBaseService.createIndependenceMch("USA");
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createRetailShopProxychain(mchId, BigDecimal.TEN, false);

			DGSQBaseService.editRetailShopProductRebate(
					productBean.getProductId(), productBean.getSellerId(),
					(long) mchId, new BigDecimal("15.00"));

			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							20238699, productBean, mchId);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0).setEarnestAmount(BigDecimal.TEN);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.getOrderItems().get(0)
					.setBookingPromotionAmount(new BigDecimal("20.00"));
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_019() {
		Logger.start(true, "创建二次确认预定订单,尚未支付，下单失败");
		try {
			// 创建一个定金订单
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			
			PlaceOrderReq bookingPlaceOrderReq = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean);
			
			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);

			long orderId = bookingPlaceOrderResp.getOrderList().get(0).getOrderId();

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);
			
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setOrderId(orderId);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setBookingConfirmOrder(true);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setEarnestDeliveryPromiseDays(0);
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.getOrders()
					.get(0)
					.setOrderItems(
							bookingPlaceOrderReq.getOrderGroups().get(0)
									.getOrders().get(0).getOrderItems());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals(String.format("%s预售订单尚不能进行二次确认！", orderId),
					placeorderCall.getMsg(), "校验msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_020() {
		Logger.start(true, "创建二次确认预定订单混合非预定商品订单，下单成功");
		try {
			Logger.comment("数据准备");
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			
			// 创建一个定金订单
			PlaceOrderReq bookingPlaceOrderReq = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean);
			
			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);
			
			Long userId = bookingPlaceOrderResp.getUserId();
			
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();
			
			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());
			
			Thread.sleep(5000);
			
			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);
			
			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean,
							bookingPlaceOrderResp.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq);
			
			secondConfirmOrderVo1.getOrderItems().get(0)
					.setProdTaxRate(new BigDecimal("0.17"));
			
			// 创建一个普通订单
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			
			OrderVo normalOrderVo = SqTradingCallService.createOrderVo(Arrays.asList(productBean1));
			
			placeOrderReq.getOrderGroups().get(0)
					.setServiceRate(new BigDecimal("13.00"));
			
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.setOrders(
							Arrays.asList(secondConfirmOrderVo1, normalOrderVo));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			List<PlaceOrderReq> bookingPlaceOrderReqList = new ArrayList<PlaceOrderReq>();

			bookingPlaceOrderReqList.add(bookingPlaceOrderReq);

			verify(bookingPlaceOrderReqList);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_021() {
		Logger.start(true,
				"创建多个二次确认订单时，使用商家优惠券，使用买手营销，使用积分，下单成功");
		try {
			Logger.comment("数据准备");
			
			// 获取下单前中免大会员可用积分和冻结积分
			PointsVo pointsVo = CDFMemberService.getCDFMemberUserPoints(
					cdfMembergoodsOwnerId, 26080783L);

			Long balance = pointsVo.getBalance();
			Long frozenBalance = pointsVo.getFrozenBalance();
			
			// 创建一个定金订单
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			
			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);
			
			bookingPlaceOrderReq1.setUserId(26080783L);
			
			OrderItemVo orderItemVo = bookingPlaceOrderReq1.getOrderGroups()
					.get(0).getOrders().get(0).getOrderItems().get(0);
			
			orderItemVo.setSku("C052901");
			orderItemVo.setProductRecordNo("C052901");

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);

			Long userId = bookingPlaceOrderResp.getUserId();

			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(userId,
							bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean1.getCurrency());
			
			Thread.sleep(5000);
			
			// 创建二个定金订单并支付
			AgentProductBean productBean2 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			
			PlaceOrderReq bookingPlaceOrderReq2 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean2);

			bookingPlaceOrderReq2.setUserId(26080783L);
			
			OrderItemVo orderItemVo2 = bookingPlaceOrderReq2.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);
			
			orderItemVo2.setSku("C052901");
			orderItemVo2.setProductRecordNo("C052901");

			TradingServiceResp bookingPlaceOrderResp2 = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq2);
			
			// 支付定金
			long thirdTradingId2 = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq2.getUserId(),
							bookingPlaceOrderResp2.getTradingId());
			BigDecimal totalPrice2 = bookingPlaceOrderResp2.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId2),
							totalPrice2.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq2.getUserId(),
							BigDecimal.ZERO.toPlainString(),
							productBean2.getCurrency());
			
			Thread.sleep(5000);
			
			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1,
							bookingPlaceOrderResp.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq1);

			OrderVo secondConfirmOrderVo2 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean2,
							bookingPlaceOrderResp2.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq2);

			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);
			
			groupVo.setSellerId(cdfMembergoodsOwnerId);
			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1,
					secondConfirmOrderVo2));

			// 使用买手优惠券
			long sellerId = groupVo.getSellerId();

			CouponVo sellerCoupon1 = SqTradingCallService.createSellerCouponVo(
					26080783L, sellerId, new BigDecimal(30), BigDecimal.TEN);

			groupVo.setSellerCoupon(sellerCoupon1);

			// 定义买手营销信息list
			List<SellerPromotionVo> sellerPromotionList = new ArrayList<SellerPromotionVo>();

			SellerPromotionVo sellerPromotion1 = new SellerPromotionVo();

			sellerPromotion1.setAmountCondition(new BigDecimal(50));
			sellerPromotion1.setId(123456789);
			sellerPromotion1.setName("自动化商家优惠活动");

			sellerPromotion1.setPromotionValue(new BigDecimal(12));
			sellerPromotion1.setQtyCondition(4);

			sellerPromotion1.setReducedAmount(new BigDecimal(15));
			sellerPromotion1.setType(PromotionTypeEnum.ReduceIfAmountEnough);

			sellerPromotion1.setApportions(Arrays.asList(
					new CatalogApportionVo(orderItemVo.getCatalogId(),
							orderItemVo.getProductNum()),
					new CatalogApportionVo(orderItemVo2.getCatalogId(),
							orderItemVo2.getProductNum())));

			sellerPromotionList.add(sellerPromotion1);

			groupVo.setSellerPromotionApportions(sellerPromotionList);

			placeOrderReq.setOrderGroups(Lists.newArrayList(groupVo));
			
			placeOrderReq.setIntegral(10L);
			placeOrderReq.setIntegralServiceType(2);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			List<PlaceOrderReq> bookingPlaceOrderReqList = Arrays.asList(
					bookingPlaceOrderReq1, bookingPlaceOrderReq2);

			verify(bookingPlaceOrderReqList);
			
			// 获取下单后中免大会员可用积分和冻结积分
			PointsVo afterPointsVo = CDFMemberService.getCDFMemberUserPoints(
					cdfMembergoodsOwnerId, 26080783L);

			Logger.verifyEquals(balance - placeOrderReq.getIntegral(),
					afterPointsVo.getBalance(), "验证下单后的balance");
			Logger.verifyEquals(frozenBalance + placeOrderReq.getIntegral(),
					afterPointsVo.getFrozenBalance(), "验证下单后的frozenBalance");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_022() {
		Logger.start(true, "创建同一个主单，两个预定订单，已经支付定金，创建二次确认订单时，使用大会员电子券+区域折扣，下单成功");
		try {
			Logger.comment("数据准备");
			
			// 创建一个定金订单
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);

			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);

			bookingPlaceOrderReq1.setUserId(26080783L);

			OrderItemVo orderItemVo = bookingPlaceOrderReq1.getOrderGroups()
					.get(0).getOrders().get(0).getOrderItems().get(0);

			orderItemVo.setSku("C042283");
			orderItemVo.setProductRecordNo("C042283");

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);

			Long userId = bookingPlaceOrderResp.getUserId();

			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(userId,
							bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean1.getCurrency());

			// 创建二个定金订单并支付
			AgentProductBean productBean2 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);

			PlaceOrderReq bookingPlaceOrderReq2 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean2);

			bookingPlaceOrderReq2.setUserId(26080783L);

			OrderItemVo orderItemVo2 = bookingPlaceOrderReq2.getOrderGroups()
					.get(0).getOrders().get(0).getOrderItems().get(0);

			orderItemVo2.setSku("C042283");
			orderItemVo2.setProductRecordNo("C042283");

			TradingServiceResp bookingPlaceOrderResp2 = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq2);

			// 支付定金
			long thirdTradingId2 = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq2.getUserId(),
							bookingPlaceOrderResp2.getTradingId());
			BigDecimal totalPrice2 = bookingPlaceOrderResp2.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId2),
							totalPrice2.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq2.getUserId(),
							BigDecimal.ZERO.toPlainString(),
							productBean2.getCurrency());
			

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1,
							bookingPlaceOrderResp.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq1);

			OrderVo secondConfirmOrderVo2 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean2,
							bookingPlaceOrderResp2.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq2);
			
			// 使用区域折扣
			secondConfirmOrderVo1
					.setRegionDiscountRatio(new BigDecimal("9.00"));

			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);
			
			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1,
					secondConfirmOrderVo2));

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setRegionDiscountRatio(new BigDecimal("9.00"));
			
			OrderGroupVo groupVo1 = new OrderGroupVo();
			
			groupVo1.setSellerId(cdfMembergoodsOwnerId);
			groupVo1.setSellerLoginId("cdfMembergoodsOwnerId");
			
			// 领取cdf优惠券
			CDFMemberService.getCdfCoupon(CouponTypeEnum.FULL_REDUCTION_COUPON
					.getCode(), 1, 26080783L);

			CouponVo couponVo = SqTradingCallService.createCouponVo(
					CDFMemberService.getLatestUnuseCdfCoupon(26080783L, cdfMembergoodsOwnerId), BigDecimal.TEN);

			couponVo.setCouponSource(1);
			couponVo.setCouponType(CouponTypeEnum.FULL_REDUCTION_COUPON
					.getCode());
			
			placeOrderReq.getOrderGroups().get(0).setSellerCoupon(couponVo);

			placeOrderReq.setIntegralServiceType(2);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			List<PlaceOrderReq> bookingPlaceOrderReqList = Arrays.asList(
					bookingPlaceOrderReq1, bookingPlaceOrderReq2);

			verify(bookingPlaceOrderReqList);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_023() {
		Logger.start(true,
				"创建同一个主单，两个已经支付定金的预定订单，一个普通订单，创建二次确认订单时，使用优惠券，使用买手营销，下单成功");
		try {
			Logger.comment("数据准备");

			// 创建一个定金订单
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);

			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);

			bookingPlaceOrderReq1.setUserId(26080783L);

			OrderItemVo orderItemVo = bookingPlaceOrderReq1.getOrderGroups()
					.get(0).getOrders().get(0).getOrderItems().get(0);

			orderItemVo.setSku("C052901");
			orderItemVo.setProductRecordNo("C052901");

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);

			Long userId = bookingPlaceOrderResp.getUserId();

			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(userId,
							bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean1.getCurrency());
			
			Thread.sleep(5000);

			// 创建二个定金订单并支付
			AgentProductBean productBean2 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);

			PlaceOrderReq bookingPlaceOrderReq2 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean2);

			bookingPlaceOrderReq2.setUserId(26080783L);

			OrderItemVo orderItemVo2 = bookingPlaceOrderReq2.getOrderGroups()
					.get(0).getOrders().get(0).getOrderItems().get(0);

			orderItemVo2.setSku("C052901");
			orderItemVo2.setProductRecordNo("C052901");

			TradingServiceResp bookingPlaceOrderResp2 = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq2);

			// 支付定金
			long thirdTradingId2 = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq2.getUserId(),
							bookingPlaceOrderResp2.getTradingId());
			BigDecimal totalPrice2 = bookingPlaceOrderResp2.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId2),
							totalPrice2.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq2.getUserId(),
							BigDecimal.ZERO.toPlainString(),
							productBean2.getCurrency());
			
			Thread.sleep(5000);

			// 创建一个普通商品
			AgentProductBean productBean3 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);
			
			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1,
							bookingPlaceOrderResp.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq1);
			
			secondConfirmOrderVo1.getOrderItems().get(0)
					.setFullReductionFreeFreight(true);

			OrderVo secondConfirmOrderVo2 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean2,
							bookingPlaceOrderResp2.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq2);

			OrderVo normalOrderVo = SqTradingCallService.createOrderVo(Arrays
					.asList(productBean3));

			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

			groupVo.setSellerId(cdfMembergoodsOwnerId);
			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1,
					secondConfirmOrderVo2, normalOrderVo));

			// 使用买手优惠券
			long sellerId = groupVo.getSellerId();

			CouponVo sellerCoupon1 = SqTradingCallService.createSellerCouponVo(
					26080783L, sellerId, new BigDecimal(30), BigDecimal.TEN);

			groupVo.setSellerCoupon(sellerCoupon1);

			// 定义买手营销信息list
			List<SellerPromotionVo> sellerPromotionList = new ArrayList<SellerPromotionVo>();

			SellerPromotionVo sellerPromotion1 = new SellerPromotionVo();

			sellerPromotion1.setAmountCondition(new BigDecimal(50));
			sellerPromotion1.setId(123456789);
			sellerPromotion1.setName("自动化商家优惠活动");

			sellerPromotion1.setPromotionValue(new BigDecimal(12));
			sellerPromotion1.setQtyCondition(4);

			sellerPromotion1.setReducedAmount(new BigDecimal(15));
			sellerPromotion1.setType(PromotionTypeEnum.ReduceIfAmountEnough);

			sellerPromotion1.setApportions(Arrays.asList(
					new CatalogApportionVo(orderItemVo.getCatalogId(),
							orderItemVo.getProductNum()),
					new CatalogApportionVo(orderItemVo2.getCatalogId(),
							orderItemVo2.getProductNum())));

			sellerPromotionList.add(sellerPromotion1);

			groupVo.setSellerPromotionApportions(sellerPromotionList);

			placeOrderReq.setDiscount(BigDecimal.TEN);
			placeOrderReq.setOrderGroups(Lists.newArrayList(groupVo));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();
			
			List<PlaceOrderReq> bookingPlaceOrderReqList = Arrays.asList(
					bookingPlaceOrderReq1, bookingPlaceOrderReq2);

			verify(bookingPlaceOrderReqList);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_024() {
		Logger.start(true, "二次确认下单后，超时取消(新接口)，退回到定金已付款状态，再次二次确认");
		try {
			Logger.comment("数据准备");

			// 创建第一个定金订单并支付
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);

			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);

			bookingPlaceOrderReq1.setUserId(26080783L);

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);
			
			long bookingOrderId = bookingPlaceOrderResp.getOrderList().get(0)
					.getOrderId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq1.getUserId(),
							bookingPlaceOrderResp.getTradingId());
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId), totalPrice
							.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq1.getUserId(),
							BigDecimal.ZERO.toPlainString(), productBean1
									.getCurrency());
			
			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1, bookingOrderId,
							bookingPlaceOrderReq1);
			
			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);
			
			secondConfirmOrderVo1.getOrderItems().get(0)
					.setFullReductionFreeFreight(true);

			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 修改二次确认时间
			orderShardingWapper.clearCache();

			OrderPo record = orderShardingWapper
					.selectOrderbyOrderId(bookingOrderId);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.DAY_OF_MONTH, -10);

			record.setSecondConfirmTime(calendar.getTime());

			// 修改二次确认时间
			orderShardingWapper.orderMapper.updateByPrimaryKey(record);

			// 自动取消二次确认订单
			SqTradingBookingOrderCallService.bookingOrderUnPaidFullAmountAutoCancel(bookingOrderId);
			
			secondConfirmOrderVo1.getOrderItems().get(0)
					.setFullReductionFreeFreight(false);
		
			placeOrderReq.setMainOrderId(SqTradingCallService
					.genMainOrderId(placeOrderReq.getUserId()));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(Arrays.asList(bookingPlaceOrderReq1));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_025() {
		Logger.start(true, "二次确认下单后，再次二次确认失败");
		try {
			Logger.comment("数据准备");

			// 创建第一个定金订单并支付
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);

			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);

			bookingPlaceOrderReq1.setUserId(26080783L);

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);

			long bookingOrderId = bookingPlaceOrderResp.getOrderList().get(0)
					.getOrderId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq1.getUserId(),
							bookingPlaceOrderResp.getTradingId());
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId), totalPrice
							.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq1.getUserId(),
							BigDecimal.ZERO.toPlainString(), productBean1
									.getCurrency());
			
			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1, bookingOrderId,
							bookingPlaceOrderReq1);

			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 再次二次确认
			placeorderCall.callService();

			Logger.verifyEquals(400, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(100, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals(
					String.format("%s预售订单尚不能进行二次确认！", bookingOrderId),
					placeorderCall.getMsg(), "校验msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_026() {
		Logger.start(true, "分销小店创建二次确认订单,下单成功");
		try {
			Logger.comment("数据准备");

			// 创建第一个定金订单并支付
			Integer mchId = DGSQBaseService.createIndependenceMch("USA");
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createRetailShopProxychain(mchId, BigDecimal.TEN, false);

			DGSQBaseService.editRetailShopProductRebate(
					productBean1.getProductId(), productBean1.getSellerId(),
					(long) mchId, new BigDecimal("15.00"));

			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);

			bookingPlaceOrderReq1.setUserId(26080783L);

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);

			long bookingOrderId = bookingPlaceOrderResp.getOrderList().get(0)
					.getOrderId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq1.getUserId(),
							bookingPlaceOrderResp.getTradingId());
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId), totalPrice
							.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq1.getUserId(),
							BigDecimal.ZERO.toPlainString(), productBean1
									.getCurrency());
			
			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1, bookingOrderId,
							bookingPlaceOrderReq1);

			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(Arrays.asList(bookingPlaceOrderReq1));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_027() {
		Logger.start(true, "创建二次确认组合商品子码预定订单混合非预定商品订单，下单成功");
		try {
			Logger.comment("数据准备");

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createComposeProductProxychain(
							(int) multiCDFCodeGoodsOwnerId, false, true);
			
			// 创建一个定金订单
			PlaceOrderReq bookingPlaceOrderReq = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean);
			
			OrderItemVo orderItemVo1 = bookingPlaceOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
			orderItemVo1.setSubProduct(true);
			
			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);
			
			Long userId = bookingPlaceOrderResp.getUserId();
			
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();
			
			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());
			
			Thread.sleep(5000);
			
			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);
			
			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean,
							bookingPlaceOrderResp.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq);
			
			secondConfirmOrderVo1.getOrderItems().get(0)
					.setProdTaxRate(new BigDecimal("0.17"));
			
			// 创建一个普通订单
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createComposeProductProxychain(
							(int) multiCDFCodeGoodsOwnerId, false, true);
			
			OrderVo normalOrderVo = SqTradingCallService.createOrderVo(Arrays.asList(productBean1));
			
			normalOrderVo.getOrderItems().get(0).setSubProduct(true);
			
			placeOrderReq.getOrderGroups().get(0)
					.setServiceRate(new BigDecimal("13.00"));
			
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.setOrders(
							Arrays.asList(secondConfirmOrderVo1, normalOrderVo));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(Arrays.asList(bookingPlaceOrderReq));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_028() {
		Logger.start(true, "二次确认下单后，带有所有优惠类型，超出支付时间取消(新接口)，退回到定金已付款状态，再次二次确认，去除所有优惠类型");
		try {
			Logger.comment("数据准备");

			// 获取下单前中免大会员可用积分和冻结积分
			PointsVo pointsVo = CDFMemberService.getCDFMemberUserPoints(
					cdfMembergoodsOwnerId, 26080783L);

			Long balance = pointsVo.getBalance();
			Long frozenBalance = pointsVo.getFrozenBalance();

			// 创建一个定金订单
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createMultiCodeProxychain((int) cdfMembergoodsOwnerId, false);

			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);

			bookingPlaceOrderReq1.getOrderGroups().get(0).getOrders().get(0).getOrderItems().get(0).setSku("C042283");
			bookingPlaceOrderReq1.getOrderGroups().get(0).getOrders().get(0).getOrderItems().get(0).setProductRecordNo("C042283");

			bookingPlaceOrderReq1.setUserId(26080783L);

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);
			
			long bookingOrderId = bookingPlaceOrderResp.getOrderList().get(0)
					.getOrderId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq1.getUserId(),
							bookingPlaceOrderResp.getTradingId());
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId), totalPrice
							.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq1.getUserId(),
							BigDecimal.ZERO.toPlainString(), productBean1
									.getCurrency());
			
			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1, bookingOrderId,
							bookingPlaceOrderReq1);
			
			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);
			
			OrderItemVo orderItemVo = secondConfirmOrderVo1.getOrderItems().get(0);
			
			// 设置满减包邮
			orderItemVo.setFullReductionFreeFreight(true);
			// 设置税率
			orderItemVo.setProdTaxRate(new BigDecimal("0.15"));
			orderItemVo.setSku("C042283");
			orderItemVo.setProductRecordNo("C042283");
			orderItemVo.setDomesticProduct(true);
			
			// 使用区域折扣
			secondConfirmOrderVo1
					.setRegionDiscountRatio(new BigDecimal("9.00"));

			// 使用cdf优惠券
			OrderGroupVo groupVo1 = new OrderGroupVo();

			groupVo1.setSellerId(cdfMembergoodsOwnerId);
			groupVo1.setSellerLoginId("cdfMembergoodsOwnerId");

			// 领取cdf优惠券
			CDFMemberService.getCdfCoupon(
					CouponTypeEnum.FULL_REDUCTION_COUPON.getCode(), 1,
					26080783L);

			CouponVo couponVo = SqTradingCallService.createCouponVo(
					CDFMemberService.getLatestUnuseCdfCoupon(26080783L,
							cdfMembergoodsOwnerId), BigDecimal.TEN);

			couponVo.setCouponSource(1);
			couponVo.setCouponType(CouponTypeEnum.FULL_REDUCTION_COUPON
					.getCode());

			placeOrderReq.getOrderGroups().get(0).setSellerCoupons(Arrays.asList(couponVo));
			
			// 设置服务费
			placeOrderReq.getOrderGroups().get(0)
					.setServiceRate(new BigDecimal("0.17"));

			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));
			
			placeOrderReq.setIntegral(10L);
			placeOrderReq.setIntegralServiceType(2);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 修改二次确认时间
			orderShardingWapper.clearCache();

			OrderPo record = orderShardingWapper
					.selectOrderbyOrderId(bookingOrderId);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.DAY_OF_MONTH, -10);

			record.setSecondConfirmTime(calendar.getTime());
			
			orderShardingWapper.orderMapper.updateByPrimaryKey(record);

			// 支付时间超时，自动取消二次确认订单
			SqTradingBookingOrderCallService.bookingOrderUnPaidFullAmountAutoCancel(bookingOrderId);
			
			// 去除满减包邮
			orderItemVo.setFullReductionFreeFreight(false);
			// 去除税率
			orderItemVo.setProdTaxRate(null);

			// 去除区域折扣
			secondConfirmOrderVo1
					.setRegionDiscountRatio(null);
			
			placeOrderReq.getOrderGroups().get(0).setSellerCoupons(null);

			// 去除服务费
			placeOrderReq.getOrderGroups().get(0)
					.setServiceRate(null);
			
			placeOrderReq.setIntegral(100L);
			placeOrderReq.setIntegralServiceType(2);
		
			placeOrderReq.setMainOrderId(SqTradingCallService
					.genMainOrderId(placeOrderReq.getUserId()));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(Arrays.asList(bookingPlaceOrderReq1));
			
			// 获取下单后中免大会员可用积分和冻结积分
			PointsVo afterPointsVo = CDFMemberService.getCDFMemberUserPoints(
					cdfMembergoodsOwnerId, 26080783L);

			Logger.verifyEquals(balance - placeOrderReq.getIntegral(),
					afterPointsVo.getBalance(), "验证下单后的balance");
			Logger.verifyEquals(frozenBalance + placeOrderReq.getIntegral(),
					afterPointsVo.getFrozenBalance(), "验证下单后的frozenBalance");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_029() {
		Logger.start(true,
				"二次确认下单后，带有多张优惠券，超出支付时间取消(新接口)，退回到定金已付款状态，再次二次确认，去除所有优惠类型");
		try {
			Logger.comment("数据准备");

			// 创建一个定金订单
			AgentProductBean productBean1 = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);

			PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean1);

			bookingPlaceOrderReq1.getOrderGroups().get(0).getOrders().get(0).getOrderItems().get(0).setSku("C052901");
			bookingPlaceOrderReq1.getOrderGroups().get(0).getOrders().get(0).getOrderItems().get(0).setProductRecordNo("C052901");

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq1);

			long bookingOrderId = bookingPlaceOrderResp.getOrderList().get(0)
					.getOrderId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService
					.payBookingOrder(bookingPlaceOrderReq1.getUserId(),
							bookingPlaceOrderResp.getTradingId());
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

			// 支付网关支付回调交易
			SQPayGateWayCallService
					.DGSQNotifyCall(String.valueOf(thirdTradingId), totalPrice
							.subtract(BigDecimal.ZERO).toString(),
							(int) bookingPlaceOrderReq1.getUserId(),
							BigDecimal.ZERO.toPlainString(), productBean1
									.getCurrency());

			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean1);

			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean1, bookingOrderId,
							bookingPlaceOrderReq1);

			OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

			OrderItemVo orderItemVo = secondConfirmOrderVo1.getOrderItems()
					.get(0);

			// 设置满减包邮
			orderItemVo.setFullReductionFreeFreight(true);
			// 设置税率
			orderItemVo.setProdTaxRate(new BigDecimal("0.15"));
			orderItemVo.setSku("C052901");
			orderItemVo.setProductRecordNo("C052901");

			// 优惠券
			OrderGroupVo groupVo1 = new OrderGroupVo();

			groupVo1.setSellerId(autotest_goodsOwnerId);
			groupVo1.setSellerLoginId("autotest_goodsOwnerId");

			// 领取cdf优惠券
			CouponVo couponVo1 = SqTradingCallService.createSellerCouponVo(
					20238699L, autotest_goodsOwnerId, new BigDecimal("50.00"),
					BigDecimal.TEN);

			CouponVo couponVo2 = SqTradingCallService.createSellerCouponVo(
					20238699L, autotest_goodsOwnerId, new BigDecimal("50.00"),
					new BigDecimal("15.00"));
			
			couponVo2.setCouponType(CouponTypeEnum.FULL_DISCOUNT_COUPON
					.getCode());

			placeOrderReq.getOrderGroups().get(0)
					.setSellerCoupons(Arrays.asList(couponVo1, couponVo2));

			// 设置服务费
			placeOrderReq.getOrderGroups().get(0)
					.setServiceRate(new BigDecimal("0.17"));

			groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 修改二次确认时间
			orderShardingWapper.clearCache();

			OrderPo record = orderShardingWapper
					.selectOrderbyOrderId(bookingOrderId);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.DAY_OF_MONTH, -10);

			record.setSecondConfirmTime(calendar.getTime());

			orderShardingWapper.orderMapper.updateByPrimaryKey(record);

			// 支付时间超时，自动取消二次确认订单
			SqTradingBookingOrderCallService
					.bookingOrderUnPaidFullAmountAutoCancel(bookingOrderId);

			// 去除满减包邮
			orderItemVo.setFullReductionFreeFreight(false);
			// 去除税率
			orderItemVo.setProdTaxRate(null);

			// 去除区域折扣
			secondConfirmOrderVo1.setRegionDiscountRatio(null);

			placeOrderReq.getOrderGroups().get(0).setSellerCoupons(null);
			
//			placeOrderReq.getOrderGroups().get(0).setSellerCoupons(Arrays.asList(couponVo1));

			// 去除服务费
			placeOrderReq.getOrderGroups().get(0).setServiceRate(null);

			placeOrderReq.setMainOrderId(SqTradingCallService
					.genMainOrderId(placeOrderReq.getUserId()));

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(Arrays.asList(bookingPlaceOrderReq1));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_030() {
		Logger.start(true, "创建二次确认预定订单，修改自提人姓名和手机号，下单成功");
		try {
			Logger.comment("数据准备");
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);
			
			// 创建一个定金订单
			PlaceOrderReq bookingPlaceOrderReq = SqTradingBookingOrderCallService
					.placeBookingOrderReq(productBean);
			
			bookingPlaceOrderReq.setPickupInStores(true);
			PickInStoreVo pickInStoreVo = new PickInStoreVo();

			pickInStoreVo.setPickupStoreId((long) TestDataManager
					.getRandomIntNum(6));
			pickInStoreVo.setPickupType(0);
			pickInStoreVo.setPickupUserName(TestDataManager.getChineseName());
			pickInStoreVo.setPickupUserPhone(TestDataManager.getPhoneNum());
			pickInStoreVo.setUserReserveTimeSpanStart(YMTDateUtil
					.getBeforeOrNextDate(0));
			pickInStoreVo.setUserReserveTimeSpanEnd(YMTDateUtil
					.getBeforeOrNextDate(10));

			bookingPlaceOrderReq.setPickInStoreVo(pickInStoreVo);
			
			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);
			
			Long userId = bookingPlaceOrderResp.getUserId();
			
			BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();
			
			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());
			
			Thread.sleep(5000);
			
			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);
			
			OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
					.createSecondConfirmOrderVo(productBean,
							bookingPlaceOrderResp.getOrderList().get(0)
									.getOrderId(), bookingPlaceOrderReq);
			
			secondConfirmOrderVo1.getOrderItems().get(0)
					.setProdTaxRate(new BigDecimal("0.17"));
			
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.setOrders(
							Arrays.asList(secondConfirmOrderVo1));
			
			pickInStoreVo.setPickupStoreId((long) TestDataManager
					.getRandomIntNum(6));
			pickInStoreVo.setPickupType(0);
			pickInStoreVo.setPickupUserName(TestDataManager.getChineseName());
			pickInStoreVo.setPickupUserPhone(TestDataManager.getPhoneNum());
			pickInStoreVo.setUserReserveTimeSpanStart(YMTDateUtil
					.getBeforeOrNextDate(0));
			pickInStoreVo.setUserReserveTimeSpanEnd(YMTDateUtil
					.getBeforeOrNextDate(10));
			
			placeOrderReq.setPickInStoreVo(pickInStoreVo);
			placeOrderReq.setPickupInStores(true);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			List<PlaceOrderReq> bookingPlaceOrderReqList = new ArrayList<PlaceOrderReq>();

			bookingPlaceOrderReqList.add(bookingPlaceOrderReq);

			verify(bookingPlaceOrderReqList);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_031() {
		Logger.start(true, "创建预定订单,使用预售库存，下单成功");
		try {

			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					false, 5);

			placeOrderReq = SqTradingCallService
					.buildDGSQStandPlaceOrderReq(4321, BigDecimal.ZERO,
							26080783, productBean, (int) autotest_goodsOwnerId,
							false);

			OrderVo orderVo = placeOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setActivity(activityVo);

			orderItemVo.setEarnestAmount(
							TestDataManager.randomPrice(BigDecimal.ZERO,
									BigDecimal.TEN));
			orderItemVo.setDomesticProduct(true);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());
			orderVo.setEarnestDeliveryPromiseDays(1);

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_032() {
		Logger.start(true, "创建预定订单,一品多码商品，使用预售库存，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychainForPreSale(
							(int) multiCDFCodeGoodsOwnerId, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					true, 5);

			placeOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			OrderVo orderVo = placeOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setProductNum(3);
			orderItemVo.setActivity(activityVo);
			orderItemVo.setEarnestAmount(BigDecimal.TEN);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(null);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_033() {
		Logger.start(true, "创建预定订单,一品多码组合商品，使用预售库存，下单库存数量超过活动预售库存，下单失败");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychainForPreSale(
							(int) multiCDFCodeGoodsOwnerId, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					true, 5);

			placeOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			OrderVo orderVo = placeOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setProductNum(10);
			orderItemVo.setActivity(activityVo);
			orderItemVo.setEarnestAmount(BigDecimal.TEN);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			Logger.verifyEquals(201, placeorderCall.getCode(), "校验code");
			Logger.verifyEquals(108, placeorderCall.getBcode(), "校验bcode");

			Logger.verifyEquals(String.format("商品库存不足|活动商品库存不足，CatalogId:%s, ActivityId:%s",
					orderItemVo.getCatalogId(), activityId),
					placeorderCall.getMsg(), "校验msg");
			Logger.verifyEquals(false,
					placeorderCall.getData().getBoolean("success"), "校验success");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SqBookingPlaceOrder_034() {
		Logger.start(true, "创建预定订单,一品多码商品，使用预售库存，定金支付时没有足够库存核销，" +
				"创建一个二次确认订单，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychainForPreSale(
							(int) multiCDFCodeGoodsOwnerId, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					true, 20);

			PlaceOrderReq bookingPlaceOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			OrderVo orderVo = bookingPlaceOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setProductNum(10);
			orderItemVo.setActivity(activityVo);
			orderItemVo.setEarnestAmount(BigDecimal.TEN);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);

			Long userId = bookingPlaceOrderReq.getUserId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					bookingPlaceOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());

			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setOrderId(bookingPlaceOrderResp.getOrderList().get(0).getOrderId());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setBookingConfirmOrder(true);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setEarnestDeliveryPromiseDays(0);
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.getOrders()
					.get(0)
					.setOrderItems(
							bookingPlaceOrderReq.getOrderGroups().get(0)
									.getOrders().get(0).getOrderItems());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			verify(Arrays.asList(bookingPlaceOrderReq));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_SqBookingPlaceOrder_035() {
		Logger.start(true, "创建预定订单,一品多码商品，使用预售库存，定金支付时没有足够库存核销，" +
				"创建一个二次确认订单，添加库存并核销，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychainForPreSale(
							(int) multiCDFCodeGoodsOwnerId, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					true, 10);

			PlaceOrderReq bookingPlaceOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			OrderVo orderVo = bookingPlaceOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setProductNum(10);
			orderItemVo.setActivity(activityVo);
			orderItemVo.setEarnestAmount(BigDecimal.TEN);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);

			Long userId = bookingPlaceOrderReq.getUserId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					bookingPlaceOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());

			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setOrderId(bookingPlaceOrderResp.getOrderList().get(0).getOrderId());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setBookingConfirmOrder(true);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setEarnestDeliveryPromiseDays(0);
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.getOrders()
					.get(0)
					.setOrderItems(
							bookingPlaceOrderReq.getOrderGroups().get(0)
									.getOrders().get(0).getOrderItems());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 添加实际库存
			SqStockService.OpenAdjustStock(multiCDFCodeGoodsOwnerId,
					orderItemVo.getProductId(), orderItemVo.getCatalogId());

			Thread.sleep(60000);

			verify(Arrays.asList(bookingPlaceOrderReq), true);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_SqBookingPlaceOrder_036() {
		Logger.start(true, "创建预定订单,多个一品多码商品，使用预售库存，" +
				"其中一个商品定金支付时没有足够库存核销，添加库存并核销，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychainForPreSale(
							(int) multiCDFCodeGoodsOwnerId, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					true, 10);

			PlaceOrderReq bookingPlaceOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			OrderVo orderVo = bookingPlaceOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setProductNum(10);
			orderItemVo.setActivity(activityVo);
			orderItemVo.setEarnestAmount(BigDecimal.TEN);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			OrderItemVo orderItemVo2 = SqTradingCallService.createOrderItemVo(
					productBean.getProductId(), productBean.getCatalogList().get(1));

			orderItemVo2.setProductNum(5);
			orderItemVo2.setActivity(activityVo);
			orderItemVo2.setEarnestAmount(BigDecimal.TEN);
			orderItemVo2.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.getOrderItems().add(orderItemVo2);
			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);

			Long userId = bookingPlaceOrderReq.getUserId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					bookingPlaceOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());

			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setOrderId(bookingPlaceOrderResp.getOrderList().get(0).getOrderId());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setBookingConfirmOrder(true);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setEarnestDeliveryPromiseDays(0);
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.getOrders()
					.get(0)
					.setOrderItems(
							bookingPlaceOrderReq.getOrderGroups().get(0)
									.getOrders().get(0).getOrderItems());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 添加实际库存
			SqStockService.OpenAdjustStock(multiCDFCodeGoodsOwnerId,
					orderItemVo.getProductId(), orderItemVo.getCatalogId());

			Thread.sleep(60000);

			verify(Arrays.asList(bookingPlaceOrderReq), true);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_SqBookingPlaceOrder_037() {
		Logger.start(true, "创建预定订单,多个一品多码商品，使用预售库存，" +
				"所有商品定金支付时没有足够库存核销，其中一个商品添加库存并核销，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychainForPreSale(
							(int) multiCDFCodeGoodsOwnerId, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					true, 10);

			PlaceOrderReq bookingPlaceOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			OrderVo orderVo = bookingPlaceOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setProductNum(10);
			orderItemVo.setActivity(activityVo);
			orderItemVo.setEarnestAmount(BigDecimal.TEN);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			OrderItemVo orderItemVo2 = SqTradingCallService.createOrderItemVo(
					productBean.getProductId(), productBean.getCatalogList().get(1));

			orderItemVo2.setProductNum(10);
			orderItemVo2.setActivity(activityVo);
			orderItemVo2.setEarnestAmount(BigDecimal.TEN);
			orderItemVo2.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.getOrderItems().add(orderItemVo2);
			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);

			Long userId = bookingPlaceOrderReq.getUserId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					bookingPlaceOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());

			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setOrderId(bookingPlaceOrderResp.getOrderList().get(0).getOrderId());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setBookingConfirmOrder(true);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setEarnestDeliveryPromiseDays(0);
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.getOrders()
					.get(0)
					.setOrderItems(
							bookingPlaceOrderReq.getOrderGroups().get(0)
									.getOrders().get(0).getOrderItems());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 添加实际库存
			SqStockService.OpenAdjustStock(multiCDFCodeGoodsOwnerId,
					orderItemVo.getProductId(), orderItemVo.getCatalogId());

			Thread.sleep(60000);

			verify(Arrays.asList(bookingPlaceOrderReq), false);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_SqBookingPlaceOrder_038() {
		Logger.start(true, "创建预定订单,多个一品多码商品，使用预售库存，" +
				"所有商品定金支付时没有足够库存核销，所有商品添加库存并核销，下单成功");
		try {
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createMultiCodeProxychainForPreSale(
							(int) multiCDFCodeGoodsOwnerId, false);

			int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
					true, 10);

			PlaceOrderReq bookingPlaceOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
					4321, BigDecimal.ZERO, 20238699, productBean,
					(int) multiCDFCodeGoodsOwnerId);

			OrderVo orderVo = bookingPlaceOrderReq.getOrderGroups().get(0).getOrders().get(0);
			OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

			ActivityVo activityVo = new ActivityVo();

			activityVo.setActivityId(activityId);
			activityVo.setActivityTemplateId(5123);
			activityVo.setAfterActivityFinishAccept(true);
			activityVo.setProductInActivityId(1234);

			orderItemVo.setProductNum(10);
			orderItemVo.setActivity(activityVo);
			orderItemVo.setEarnestAmount(BigDecimal.TEN);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			OrderItemVo orderItemVo2 = SqTradingCallService.createOrderItemVo(
					productBean.getProductId(), productBean.getCatalogList().get(1));

			orderItemVo2.setProductNum(10);
			orderItemVo2.setActivity(activityVo);
			orderItemVo2.setEarnestAmount(BigDecimal.TEN);
			orderItemVo2.setBookingPromotionAmount(new BigDecimal("20.00"));

			orderVo.getOrderItems().add(orderItemVo2);
			orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
					.callPlaceOrderService(bookingPlaceOrderReq);

			Long userId = bookingPlaceOrderReq.getUserId();

			// 支付定金
			long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
					bookingPlaceOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					bookingPlaceOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString(),
					productBean.getCurrency());

			Thread.sleep(5000);

			// 创建一个二次确认订单
			placeOrderReq = SqTradingBookingOrderCallService
					.sqSimplePlaceOrderReq(bookingPlaceOrderResp.getUserId(),
							productBean);

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setOrderId(bookingPlaceOrderResp.getOrderList().get(0).getOrderId());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setBookingConfirmOrder(true);
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setEarnestDeliveryPromiseDays(0);
			placeOrderReq
					.getOrderGroups()
					.get(0)
					.getOrders()
					.get(0)
					.setOrderItems(
							bookingPlaceOrderReq.getOrderGroups().get(0)
									.getOrders().get(0).getOrderItems());

			placeorderCall.setData(placeOrderReq);
			placeorderCall.callService();

			// 添加实际库存
			SqStockService.OpenAdjustStock(multiCDFCodeGoodsOwnerId,
					orderItemVo.getProductId(), orderItemVo.getCatalogId());

			// 添加实际库存
			SqStockService.OpenAdjustStock(multiCDFCodeGoodsOwnerId,
					orderItemVo2.getProductId(), orderItemVo2.getCatalogId());

			Thread.sleep(60000);

			verify(Arrays.asList(bookingPlaceOrderReq), true);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	public static void main(String[] args) throws Exception {
		
		// 修改二次确认时间
		orderShardingWapper.clearCache();

		OrderPo record = orderShardingWapper
				.selectOrderbyOrderId(1483690783L);

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, -10);

		record.setSecondConfirmTime(calendar.getTime());

		// 修改二次确认时间
		orderShardingWapper.orderMapper.updateByPrimaryKey(record);
	}
}
